blob: 37b7923712806fd1d37f093ea4119a29e6892662 [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
Marshall Clow0ac5cce2013-10-21 14:29:37 +000043#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
Howard Hinnant99968442011-11-29 18:15:50 +000044 friend typename _Cp::__self;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000045#else
Howard Hinnant99968442011-11-29 18:15:50 +000046 friend class _Cp::__self;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000047#endif
Howard Hinnant99968442011-11-29 18:15:50 +000048 friend class __bit_const_reference<_Cp>;
49 friend class __bit_iterator<_Cp, false>;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000050public:
Howard Hinnant10f25d22011-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 Hinnantbc8d3f92010-05-11 19:42:16 +000055
56 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant10f25d22011-05-27 20:52:28 +000057 __bit_reference& operator=(bool __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000058 {
59 if (__x)
60 *__seg_ |= __mask_;
61 else
62 *__seg_ &= ~__mask_;
63 return *this;
64 }
Howard Hinnant324bb032010-08-22 00:02:43 +000065
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant10f25d22011-05-27 20:52:28 +000067 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
68 {return operator=(static_cast<bool>(__x));}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000069
Howard Hinnant10f25d22011-05-27 20:52:28 +000070 _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
Howard Hinnant99968442011-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 Hinnantbc8d3f92010-05-11 19:42:16 +000073private:
74 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant10f25d22011-05-27 20:52:28 +000075 __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
76 : __seg_(__s), __mask_(__m) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000077};
78
Howard Hinnant99968442011-11-29 18:15:50 +000079template <class _Cp>
80class __bit_reference<_Cp, false>
Howard Hinnantf03c3b42011-07-02 20:33:23 +000081{
82};
83
Howard Hinnantd9cdb2d2013-03-26 13:48:57 +000084template <class _Cp>
Howard Hinnant1e564242013-10-04 22:09:00 +000085inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd9cdb2d2013-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 Hinnant99968442011-11-29 18:15:50 +000094template <class _Cp, class _Dp>
Howard Hinnant1e564242013-10-04 22:09:00 +000095inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000096void
Howard Hinnant99968442011-11-29 18:15:50 +000097swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000098{
99 bool __t = __x;
100 __x = __y;
101 __y = __t;
102}
103
Howard Hinnant99968442011-11-29 18:15:50 +0000104template <class _Cp>
Howard Hinnant1e564242013-10-04 22:09:00 +0000105inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000106void
Howard Hinnant99968442011-11-29 18:15:50 +0000107swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000108{
109 bool __t = __x;
110 __x = __y;
111 __y = __t;
112}
113
Howard Hinnant99968442011-11-29 18:15:50 +0000114template <class _Cp>
Howard Hinnant1e564242013-10-04 22:09:00 +0000115inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000116void
Howard Hinnant99968442011-11-29 18:15:50 +0000117swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000118{
119 bool __t = __x;
120 __x = __y;
121 __y = __t;
122}
123
Howard Hinnant99968442011-11-29 18:15:50 +0000124template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000125class __bit_const_reference
126{
Howard Hinnant99968442011-11-29 18:15:50 +0000127 typedef typename _Cp::__storage_type __storage_type;
128 typedef typename _Cp::__const_storage_pointer __storage_pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000129
130 __storage_pointer __seg_;
131 __storage_type __mask_;
132
Marshall Clow0ac5cce2013-10-21 14:29:37 +0000133#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
Howard Hinnant99968442011-11-29 18:15:50 +0000134 friend typename _Cp::__self;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000135#else
Howard Hinnant99968442011-11-29 18:15:50 +0000136 friend class _Cp::__self;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000137#endif
Howard Hinnant99968442011-11-29 18:15:50 +0000138 friend class __bit_iterator<_Cp, true>;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000139public:
140 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000141 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000142 : __seg_(__x.__seg_), __mask_(__x.__mask_) {}
143
Howard Hinnant90d87232012-07-07 17:04:52 +0000144 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT
Howard Hinnant10f25d22011-05-27 20:52:28 +0000145 {return static_cast<bool>(*__seg_ & __mask_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000146
Howard Hinnant99968442011-11-29 18:15:50 +0000147 _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
148 {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000149private:
150 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant90d87232012-07-07 17:04:52 +0000151 _LIBCPP_CONSTEXPR
Howard Hinnant10f25d22011-05-27 20:52:28 +0000152 __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
153 : __seg_(__s), __mask_(__m) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000154
155 __bit_const_reference& operator=(const __bit_const_reference& __x);
156};
157
158// find
159
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000160template <class _Cp, bool _IsConst>
161__bit_iterator<_Cp, _IsConst>
162__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000163{
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000164 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000165 typedef typename _It::__storage_type __storage_type;
166 static const unsigned __bits_per_word = _It::__bits_per_word;
167 // do first partial word
168 if (__first.__ctz_ != 0)
169 {
170 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000171 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000172 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
173 __storage_type __b = *__first.__seg_ & __m;
174 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000175 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant36ba3992013-08-07 20:42:16 +0000176 if (__n == __dn)
177 return _It(__first.__seg_, __first.__ctz_ + __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000178 __n -= __dn;
179 ++__first.__seg_;
180 }
181 // do middle whole words
182 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
183 if (*__first.__seg_)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000184 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(*__first.__seg_)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000185 // do last partial word
186 if (__n > 0)
187 {
188 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
189 __storage_type __b = *__first.__seg_ & __m;
190 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000191 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000192 }
193 return _It(__first.__seg_, static_cast<unsigned>(__n));
194}
195
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000196template <class _Cp, bool _IsConst>
197__bit_iterator<_Cp, _IsConst>
198__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000199{
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000200 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000201 typedef typename _It::__storage_type __storage_type;
202 static const unsigned __bits_per_word = _It::__bits_per_word;
203 // do first partial word
204 if (__first.__ctz_ != 0)
205 {
206 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000207 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000208 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000209 __storage_type __b = ~*__first.__seg_ & __m;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000210 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000211 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant36ba3992013-08-07 20:42:16 +0000212 if (__n == __dn)
213 return _It(__first.__seg_, __first.__ctz_ + __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000214 __n -= __dn;
215 ++__first.__seg_;
216 }
217 // do middle whole words
218 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
219 {
220 __storage_type __b = ~*__first.__seg_;
221 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000222 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000223 }
224 // do last partial word
225 if (__n > 0)
226 {
227 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000228 __storage_type __b = ~*__first.__seg_ & __m;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000229 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000230 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000231 }
232 return _It(__first.__seg_, static_cast<unsigned>(__n));
233}
234
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000235template <class _Cp, bool _IsConst, class _Tp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000236inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000237__bit_iterator<_Cp, _IsConst>
238find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000239{
Howard Hinnant78b68282011-10-22 20:59:45 +0000240 if (static_cast<bool>(__value_))
Howard Hinnant99968442011-11-29 18:15:50 +0000241 return __find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
242 return __find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000243}
244
245// count
246
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000247template <class _Cp, bool _IsConst>
248typename __bit_iterator<_Cp, _IsConst>::difference_type
249__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000250{
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000251 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000252 typedef typename _It::__storage_type __storage_type;
253 typedef typename _It::difference_type difference_type;
254 static const unsigned __bits_per_word = _It::__bits_per_word;
255 difference_type __r = 0;
256 // do first partial word
257 if (__first.__ctz_ != 0)
258 {
259 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000260 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000261 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Howard Hinnant0949eed2011-06-30 21:18:19 +0000262 __r = _VSTD::__pop_count(*__first.__seg_ & __m);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000263 __n -= __dn;
264 ++__first.__seg_;
265 }
266 // do middle whole words
267 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000268 __r += _VSTD::__pop_count(*__first.__seg_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000269 // do last partial word
270 if (__n > 0)
271 {
272 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000273 __r += _VSTD::__pop_count(*__first.__seg_ & __m);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000274 }
275 return __r;
276}
277
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000278template <class _Cp, bool _IsConst>
279typename __bit_iterator<_Cp, _IsConst>::difference_type
280__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000281{
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000282 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000283 typedef typename _It::__storage_type __storage_type;
284 typedef typename _It::difference_type difference_type;
285 static const unsigned __bits_per_word = _It::__bits_per_word;
286 difference_type __r = 0;
287 // do first partial word
288 if (__first.__ctz_ != 0)
289 {
290 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000291 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000292 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000293 __r = _VSTD::__pop_count(~*__first.__seg_ & __m);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000294 __n -= __dn;
295 ++__first.__seg_;
296 }
297 // do middle whole words
298 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000299 __r += _VSTD::__pop_count(~*__first.__seg_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000300 // do last partial word
301 if (__n > 0)
302 {
303 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000304 __r += _VSTD::__pop_count(~*__first.__seg_ & __m);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000305 }
306 return __r;
307}
308
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000309template <class _Cp, bool _IsConst, class _Tp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000310inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000311typename __bit_iterator<_Cp, _IsConst>::difference_type
312count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000313{
Howard Hinnant78b68282011-10-22 20:59:45 +0000314 if (static_cast<bool>(__value_))
Howard Hinnant99968442011-11-29 18:15:50 +0000315 return __count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
316 return __count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000317}
318
319// fill_n
320
Howard Hinnant99968442011-11-29 18:15:50 +0000321template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000322void
Howard Hinnant99968442011-11-29 18:15:50 +0000323__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000324{
Howard Hinnant99968442011-11-29 18:15:50 +0000325 typedef __bit_iterator<_Cp, false> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000326 typedef typename _It::__storage_type __storage_type;
327 static const unsigned __bits_per_word = _It::__bits_per_word;
328 // do first partial word
329 if (__first.__ctz_ != 0)
330 {
331 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000332 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000333 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
334 *__first.__seg_ &= ~__m;
335 __n -= __dn;
336 ++__first.__seg_;
337 }
338 // do middle whole words
339 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000340 _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000341 __n -= __nw * __bits_per_word;
342 // do last partial word
343 if (__n > 0)
344 {
345 __first.__seg_ += __nw;
346 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
347 *__first.__seg_ &= ~__m;
348 }
349}
350
Howard Hinnant99968442011-11-29 18:15:50 +0000351template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000352void
Howard Hinnant99968442011-11-29 18:15:50 +0000353__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000354{
Howard Hinnant99968442011-11-29 18:15:50 +0000355 typedef __bit_iterator<_Cp, false> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000356 typedef typename _It::__storage_type __storage_type;
357 static const unsigned __bits_per_word = _It::__bits_per_word;
358 // do first partial word
359 if (__first.__ctz_ != 0)
360 {
361 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000362 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000363 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
364 *__first.__seg_ |= __m;
365 __n -= __dn;
366 ++__first.__seg_;
367 }
368 // do middle whole words
369 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000370 _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000371 __n -= __nw * __bits_per_word;
372 // do last partial word
373 if (__n > 0)
374 {
375 __first.__seg_ += __nw;
376 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
377 *__first.__seg_ |= __m;
378 }
379}
380
Howard Hinnant99968442011-11-29 18:15:50 +0000381template <class _Cp>
Howard Hinnant1e564242013-10-04 22:09:00 +0000382inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000383void
Howard Hinnant99968442011-11-29 18:15:50 +0000384fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000385{
386 if (__n > 0)
387 {
Howard Hinnant78b68282011-10-22 20:59:45 +0000388 if (__value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000389 __fill_n_true(__first, __n);
390 else
391 __fill_n_false(__first, __n);
392 }
393}
394
395// fill
396
Howard Hinnant99968442011-11-29 18:15:50 +0000397template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000398inline _LIBCPP_INLINE_VISIBILITY
399void
Howard Hinnant99968442011-11-29 18:15:50 +0000400fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000401{
Howard Hinnant99968442011-11-29 18:15:50 +0000402 _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000403}
404
405// copy
406
Howard Hinnant99968442011-11-29 18:15:50 +0000407template <class _Cp, bool _IsConst>
408__bit_iterator<_Cp, false>
409__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
410 __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000411{
Howard Hinnant99968442011-11-29 18:15:50 +0000412 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000413 typedef typename _In::difference_type difference_type;
414 typedef typename _In::__storage_type __storage_type;
415 static const unsigned __bits_per_word = _In::__bits_per_word;
416 difference_type __n = __last - __first;
417 if (__n > 0)
418 {
419 // do first word
420 if (__first.__ctz_ != 0)
421 {
422 unsigned __clz = __bits_per_word - __first.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000423 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000424 __n -= __dn;
425 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
426 __storage_type __b = *__first.__seg_ & __m;
427 *__result.__seg_ &= ~__m;
428 *__result.__seg_ |= __b;
429 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
430 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
431 ++__first.__seg_;
432 // __first.__ctz_ = 0;
433 }
434 // __first.__ctz_ == 0;
435 // do middle words
436 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000437 _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
438 _VSTD::__to_raw_pointer(__first.__seg_),
439 __nw * sizeof(__storage_type));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000440 __n -= __nw * __bits_per_word;
441 __result.__seg_ += __nw;
442 // do last word
443 if (__n > 0)
444 {
445 __first.__seg_ += __nw;
446 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
447 __storage_type __b = *__first.__seg_ & __m;
448 *__result.__seg_ &= ~__m;
449 *__result.__seg_ |= __b;
450 __result.__ctz_ = static_cast<unsigned>(__n);
451 }
452 }
453 return __result;
454}
455
Howard Hinnant99968442011-11-29 18:15:50 +0000456template <class _Cp, bool _IsConst>
457__bit_iterator<_Cp, false>
458__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
459 __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000460{
Howard Hinnant99968442011-11-29 18:15:50 +0000461 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000462 typedef typename _In::difference_type difference_type;
463 typedef typename _In::__storage_type __storage_type;
464 static const unsigned __bits_per_word = _In::__bits_per_word;
465 difference_type __n = __last - __first;
466 if (__n > 0)
467 {
468 // do first word
469 if (__first.__ctz_ != 0)
470 {
471 unsigned __clz_f = __bits_per_word - __first.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000472 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000473 __n -= __dn;
474 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
475 __storage_type __b = *__first.__seg_ & __m;
476 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000477 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000478 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
479 *__result.__seg_ &= ~__m;
480 if (__result.__ctz_ > __first.__ctz_)
481 *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
482 else
483 *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
484 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
485 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
486 __dn -= __ddn;
487 if (__dn > 0)
488 {
489 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
490 *__result.__seg_ &= ~__m;
491 *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
492 __result.__ctz_ = static_cast<unsigned>(__dn);
493 }
494 ++__first.__seg_;
495 // __first.__ctz_ = 0;
496 }
497 // __first.__ctz_ == 0;
498 // do middle words
499 unsigned __clz_r = __bits_per_word - __result.__ctz_;
500 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
501 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
502 {
503 __storage_type __b = *__first.__seg_;
504 *__result.__seg_ &= ~__m;
505 *__result.__seg_ |= __b << __result.__ctz_;
506 ++__result.__seg_;
507 *__result.__seg_ &= __m;
508 *__result.__seg_ |= __b >> __clz_r;
509 }
510 // do last word
511 if (__n > 0)
512 {
513 __m = ~__storage_type(0) >> (__bits_per_word - __n);
514 __storage_type __b = *__first.__seg_ & __m;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000515 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000516 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
517 *__result.__seg_ &= ~__m;
518 *__result.__seg_ |= __b << __result.__ctz_;
519 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
520 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
521 __n -= __dn;
522 if (__n > 0)
523 {
524 __m = ~__storage_type(0) >> (__bits_per_word - __n);
525 *__result.__seg_ &= ~__m;
526 *__result.__seg_ |= __b >> __dn;
527 __result.__ctz_ = static_cast<unsigned>(__n);
528 }
529 }
530 }
531 return __result;
532}
533
Howard Hinnant99968442011-11-29 18:15:50 +0000534template <class _Cp, bool _IsConst>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000535inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000536__bit_iterator<_Cp, false>
537copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000538{
539 if (__first.__ctz_ == __result.__ctz_)
540 return __copy_aligned(__first, __last, __result);
541 return __copy_unaligned(__first, __last, __result);
542}
543
544// copy_backward
545
Howard Hinnant99968442011-11-29 18:15:50 +0000546template <class _Cp, bool _IsConst>
547__bit_iterator<_Cp, false>
548__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
549 __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000550{
Howard Hinnant99968442011-11-29 18:15:50 +0000551 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000552 typedef typename _In::difference_type difference_type;
553 typedef typename _In::__storage_type __storage_type;
554 static const unsigned __bits_per_word = _In::__bits_per_word;
555 difference_type __n = __last - __first;
556 if (__n > 0)
557 {
558 // do first word
559 if (__last.__ctz_ != 0)
560 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000561 difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000562 __n -= __dn;
563 unsigned __clz = __bits_per_word - __last.__ctz_;
564 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
565 __storage_type __b = *__last.__seg_ & __m;
566 *__result.__seg_ &= ~__m;
567 *__result.__seg_ |= __b;
568 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
569 __result.__ctz_) % __bits_per_word);
570 // __last.__ctz_ = 0
571 }
572 // __last.__ctz_ == 0 || __n == 0
573 // __result.__ctz_ == 0 || __n == 0
574 // do middle words
575 __storage_type __nw = __n / __bits_per_word;
576 __result.__seg_ -= __nw;
577 __last.__seg_ -= __nw;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000578 _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
579 _VSTD::__to_raw_pointer(__last.__seg_),
580 __nw * sizeof(__storage_type));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000581 __n -= __nw * __bits_per_word;
582 // do last word
583 if (__n > 0)
584 {
585 __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
586 __storage_type __b = *--__last.__seg_ & __m;
587 *--__result.__seg_ &= ~__m;
588 *__result.__seg_ |= __b;
589 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
590 }
591 }
592 return __result;
593}
594
Howard Hinnant99968442011-11-29 18:15:50 +0000595template <class _Cp, bool _IsConst>
596__bit_iterator<_Cp, false>
597__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
598 __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000599{
Howard Hinnant99968442011-11-29 18:15:50 +0000600 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000601 typedef typename _In::difference_type difference_type;
602 typedef typename _In::__storage_type __storage_type;
603 static const unsigned __bits_per_word = _In::__bits_per_word;
604 difference_type __n = __last - __first;
605 if (__n > 0)
606 {
607 // do first word
608 if (__last.__ctz_ != 0)
609 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000610 difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000611 __n -= __dn;
612 unsigned __clz_l = __bits_per_word - __last.__ctz_;
613 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
614 __storage_type __b = *__last.__seg_ & __m;
615 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000616 __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000617 if (__ddn > 0)
618 {
619 __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
620 *__result.__seg_ &= ~__m;
621 if (__result.__ctz_ > __last.__ctz_)
622 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
623 else
624 *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
625 __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) +
626 __result.__ctz_) % __bits_per_word);
627 __dn -= __ddn;
628 }
629 if (__dn > 0)
630 {
631 // __result.__ctz_ == 0
632 --__result.__seg_;
633 __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
634 __m = ~__storage_type(0) << __result.__ctz_;
635 *__result.__seg_ &= ~__m;
636 __last.__ctz_ -= __dn + __ddn;
637 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
638 }
639 // __last.__ctz_ = 0
640 }
641 // __last.__ctz_ == 0 || __n == 0
642 // __result.__ctz_ != 0 || __n == 0
643 // do middle words
644 unsigned __clz_r = __bits_per_word - __result.__ctz_;
645 __storage_type __m = ~__storage_type(0) >> __clz_r;
646 for (; __n >= __bits_per_word; __n -= __bits_per_word)
647 {
648 __storage_type __b = *--__last.__seg_;
649 *__result.__seg_ &= ~__m;
650 *__result.__seg_ |= __b >> __clz_r;
651 *--__result.__seg_ &= __m;
652 *__result.__seg_ |= __b << __result.__ctz_;
653 }
654 // do last word
655 if (__n > 0)
656 {
657 __m = ~__storage_type(0) << (__bits_per_word - __n);
658 __storage_type __b = *--__last.__seg_ & __m;
Howard Hinnantec3773c2011-12-01 20:21:04 +0000659 __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000660 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000661 __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
662 *__result.__seg_ &= ~__m;
663 *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
664 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
665 __result.__ctz_) % __bits_per_word);
666 __n -= __dn;
667 if (__n > 0)
668 {
669 // __result.__ctz_ == 0
670 --__result.__seg_;
671 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
672 __m = ~__storage_type(0) << __result.__ctz_;
673 *__result.__seg_ &= ~__m;
674 *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
675 }
676 }
677 }
678 return __result;
679}
680
Howard Hinnant99968442011-11-29 18:15:50 +0000681template <class _Cp, bool _IsConst>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000682inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000683__bit_iterator<_Cp, false>
684copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000685{
686 if (__last.__ctz_ == __result.__ctz_)
687 return __copy_backward_aligned(__first, __last, __result);
688 return __copy_backward_unaligned(__first, __last, __result);
689}
690
691// move
692
Howard Hinnant99968442011-11-29 18:15:50 +0000693template <class _Cp, bool _IsConst>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000694inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000695__bit_iterator<_Cp, false>
696move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000697{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000698 return _VSTD::copy(__first, __last, __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000699}
700
701// move_backward
702
Howard Hinnant99968442011-11-29 18:15:50 +0000703template <class _Cp, bool _IsConst>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000704inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000705__bit_iterator<_Cp, false>
706move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000707{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000708 return _VSTD::copy(__first, __last, __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000709}
710
711// swap_ranges
712
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000713template <class __C1, class __C2>
714__bit_iterator<__C2, false>
715__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
716 __bit_iterator<__C2, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000717{
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000718 typedef __bit_iterator<__C1, false> _I1;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000719 typedef typename _I1::difference_type difference_type;
720 typedef typename _I1::__storage_type __storage_type;
721 static const unsigned __bits_per_word = _I1::__bits_per_word;
722 difference_type __n = __last - __first;
723 if (__n > 0)
724 {
725 // do first word
726 if (__first.__ctz_ != 0)
727 {
728 unsigned __clz = __bits_per_word - __first.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000729 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000730 __n -= __dn;
731 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
732 __storage_type __b1 = *__first.__seg_ & __m;
733 *__first.__seg_ &= ~__m;
734 __storage_type __b2 = *__result.__seg_ & __m;
735 *__result.__seg_ &= ~__m;
736 *__result.__seg_ |= __b1;
737 *__first.__seg_ |= __b2;
738 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
739 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
740 ++__first.__seg_;
741 // __first.__ctz_ = 0;
742 }
743 // __first.__ctz_ == 0;
744 // do middle words
745 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
746 swap(*__first.__seg_, *__result.__seg_);
747 // do last word
748 if (__n > 0)
749 {
750 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
751 __storage_type __b1 = *__first.__seg_ & __m;
752 *__first.__seg_ &= ~__m;
753 __storage_type __b2 = *__result.__seg_ & __m;
754 *__result.__seg_ &= ~__m;
755 *__result.__seg_ |= __b1;
756 *__first.__seg_ |= __b2;
757 __result.__ctz_ = static_cast<unsigned>(__n);
758 }
759 }
760 return __result;
761}
762
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000763template <class __C1, class __C2>
764__bit_iterator<__C2, false>
765__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
766 __bit_iterator<__C2, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000767{
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000768 typedef __bit_iterator<__C1, false> _I1;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000769 typedef typename _I1::difference_type difference_type;
770 typedef typename _I1::__storage_type __storage_type;
771 static const unsigned __bits_per_word = _I1::__bits_per_word;
772 difference_type __n = __last - __first;
773 if (__n > 0)
774 {
775 // do first word
776 if (__first.__ctz_ != 0)
777 {
778 unsigned __clz_f = __bits_per_word - __first.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000779 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000780 __n -= __dn;
781 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
782 __storage_type __b1 = *__first.__seg_ & __m;
783 *__first.__seg_ &= ~__m;
784 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000785 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000786 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
787 __storage_type __b2 = *__result.__seg_ & __m;
788 *__result.__seg_ &= ~__m;
789 if (__result.__ctz_ > __first.__ctz_)
790 {
791 unsigned __s = __result.__ctz_ - __first.__ctz_;
792 *__result.__seg_ |= __b1 << __s;
793 *__first.__seg_ |= __b2 >> __s;
794 }
795 else
796 {
797 unsigned __s = __first.__ctz_ - __result.__ctz_;
798 *__result.__seg_ |= __b1 >> __s;
799 *__first.__seg_ |= __b2 << __s;
800 }
801 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
802 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
803 __dn -= __ddn;
804 if (__dn > 0)
805 {
806 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
807 __b2 = *__result.__seg_ & __m;
808 *__result.__seg_ &= ~__m;
809 unsigned __s = __first.__ctz_ + __ddn;
810 *__result.__seg_ |= __b1 >> __s;
811 *__first.__seg_ |= __b2 << __s;
812 __result.__ctz_ = static_cast<unsigned>(__dn);
813 }
814 ++__first.__seg_;
815 // __first.__ctz_ = 0;
816 }
817 // __first.__ctz_ == 0;
818 // do middle words
819 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
820 unsigned __clz_r = __bits_per_word - __result.__ctz_;
821 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
822 {
823 __storage_type __b1 = *__first.__seg_;
824 __storage_type __b2 = *__result.__seg_ & __m;
825 *__result.__seg_ &= ~__m;
826 *__result.__seg_ |= __b1 << __result.__ctz_;
827 *__first.__seg_ = __b2 >> __result.__ctz_;
828 ++__result.__seg_;
829 __b2 = *__result.__seg_ & ~__m;
830 *__result.__seg_ &= __m;
831 *__result.__seg_ |= __b1 >> __clz_r;
832 *__first.__seg_ |= __b2 << __clz_r;
833 }
834 // do last word
835 if (__n > 0)
836 {
837 __m = ~__storage_type(0) >> (__bits_per_word - __n);
838 __storage_type __b1 = *__first.__seg_ & __m;
839 *__first.__seg_ &= ~__m;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000840 __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000841 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
842 __storage_type __b2 = *__result.__seg_ & __m;
843 *__result.__seg_ &= ~__m;
844 *__result.__seg_ |= __b1 << __result.__ctz_;
845 *__first.__seg_ |= __b2 >> __result.__ctz_;
846 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
847 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
848 __n -= __dn;
849 if (__n > 0)
850 {
851 __m = ~__storage_type(0) >> (__bits_per_word - __n);
852 __b2 = *__result.__seg_ & __m;
853 *__result.__seg_ &= ~__m;
854 *__result.__seg_ |= __b1 >> __dn;
855 *__first.__seg_ |= __b2 << __dn;
856 __result.__ctz_ = static_cast<unsigned>(__n);
857 }
858 }
859 }
860 return __result;
861}
862
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000863template <class __C1, class __C2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000864inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000865__bit_iterator<__C2, false>
866swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
867 __bit_iterator<__C2, false> __first2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000868{
869 if (__first1.__ctz_ == __first2.__ctz_)
870 return __swap_ranges_aligned(__first1, __last1, __first2);
871 return __swap_ranges_unaligned(__first1, __last1, __first2);
872}
873
874// rotate
875
Howard Hinnant99968442011-11-29 18:15:50 +0000876template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000877struct __bit_array
878{
Howard Hinnant99968442011-11-29 18:15:50 +0000879 typedef typename _Cp::difference_type difference_type;
880 typedef typename _Cp::__storage_type __storage_type;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000881 typedef typename _Cp::__storage_pointer __storage_pointer;
Howard Hinnant99968442011-11-29 18:15:50 +0000882 typedef typename _Cp::iterator iterator;
883 static const unsigned __bits_per_word = _Cp::__bits_per_word;
884 static const unsigned _Np = 4;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000885
886 difference_type __size_;
Howard Hinnant99968442011-11-29 18:15:50 +0000887 __storage_type __word_[_Np];
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000888
889 _LIBCPP_INLINE_VISIBILITY static difference_type capacity()
Howard Hinnant99968442011-11-29 18:15:50 +0000890 {return static_cast<difference_type>(_Np * __bits_per_word);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000891 _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000892 _LIBCPP_INLINE_VISIBILITY iterator begin()
893 {
894 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
895 }
896 _LIBCPP_INLINE_VISIBILITY iterator end()
897 {
898 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
899 static_cast<unsigned>(__size_ % __bits_per_word));
900 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000901};
902
Howard Hinnant99968442011-11-29 18:15:50 +0000903template <class _Cp>
904__bit_iterator<_Cp, false>
905rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000906{
Howard Hinnant99968442011-11-29 18:15:50 +0000907 typedef __bit_iterator<_Cp, false> _I1;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000908 typedef typename _I1::difference_type difference_type;
909 typedef typename _I1::__storage_type __storage_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000910 difference_type __d1 = __middle - __first;
911 difference_type __d2 = __last - __middle;
912 _I1 __r = __first + __d2;
913 while (__d1 != 0 && __d2 != 0)
914 {
915 if (__d1 <= __d2)
916 {
Howard Hinnant99968442011-11-29 18:15:50 +0000917 if (__d1 <= __bit_array<_Cp>::capacity())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000918 {
Howard Hinnant99968442011-11-29 18:15:50 +0000919 __bit_array<_Cp> __b(__d1);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000920 _VSTD::copy(__first, __middle, __b.begin());
921 _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000922 break;
923 }
924 else
925 {
Howard Hinnant99968442011-11-29 18:15:50 +0000926 __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000927 __first = __middle;
928 __middle = __mp;
929 __d2 -= __d1;
930 }
931 }
932 else
933 {
Howard Hinnant99968442011-11-29 18:15:50 +0000934 if (__d2 <= __bit_array<_Cp>::capacity())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000935 {
Howard Hinnant99968442011-11-29 18:15:50 +0000936 __bit_array<_Cp> __b(__d2);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000937 _VSTD::copy(__middle, __last, __b.begin());
938 _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000939 break;
940 }
941 else
942 {
Howard Hinnant99968442011-11-29 18:15:50 +0000943 __bit_iterator<_Cp, false> __mp = __first + __d2;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000944 _VSTD::swap_ranges(__first, __mp, __middle);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000945 __first = __mp;
946 __d1 -= __d2;
947 }
948 }
949 }
950 return __r;
951}
952
953// equal
954
Howard Hinnant584db422012-08-05 21:43:11 +0000955template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000956bool
Howard Hinnant584db422012-08-05 21:43:11 +0000957__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
958 __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000959{
Howard Hinnant584db422012-08-05 21:43:11 +0000960 typedef __bit_iterator<_Cp, _IC1> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000961 typedef typename _It::difference_type difference_type;
962 typedef typename _It::__storage_type __storage_type;
963 static const unsigned __bits_per_word = _It::__bits_per_word;
964 difference_type __n = __last1 - __first1;
965 if (__n > 0)
966 {
967 // do first word
968 if (__first1.__ctz_ != 0)
969 {
970 unsigned __clz_f = __bits_per_word - __first1.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000971 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000972 __n -= __dn;
973 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
974 __storage_type __b = *__first1.__seg_ & __m;
975 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000976 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000977 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
978 if (__first2.__ctz_ > __first1.__ctz_)
Howard Hinnantdbd9eac2012-05-31 23:12:03 +0000979 {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000980 if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
981 return false;
Howard Hinnantdbd9eac2012-05-31 23:12:03 +0000982 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000983 else
Howard Hinnantdbd9eac2012-05-31 23:12:03 +0000984 {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000985 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
986 return false;
Howard Hinnantdbd9eac2012-05-31 23:12:03 +0000987 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000988 __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
989 __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word);
990 __dn -= __ddn;
991 if (__dn > 0)
992 {
993 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
994 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
995 return false;
996 __first2.__ctz_ = static_cast<unsigned>(__dn);
997 }
998 ++__first1.__seg_;
999 // __first1.__ctz_ = 0;
1000 }
1001 // __first1.__ctz_ == 0;
1002 // do middle words
1003 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
1004 __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
1005 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_)
1006 {
1007 __storage_type __b = *__first1.__seg_;
1008 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
1009 return false;
1010 ++__first2.__seg_;
1011 if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
1012 return false;
1013 }
1014 // do last word
1015 if (__n > 0)
1016 {
1017 __m = ~__storage_type(0) >> (__bits_per_word - __n);
1018 __storage_type __b = *__first1.__seg_ & __m;
Howard Hinnant0949eed2011-06-30 21:18:19 +00001019 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001020 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
1021 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
1022 return false;
1023 __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
1024 __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word);
1025 __n -= __dn;
1026 if (__n > 0)
1027 {
1028 __m = ~__storage_type(0) >> (__bits_per_word - __n);
1029 if ((*__first2.__seg_ & __m) != (__b >> __dn))
1030 return false;
1031 }
1032 }
1033 }
1034 return true;
1035}
1036
Howard Hinnant584db422012-08-05 21:43:11 +00001037template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001038bool
Howard Hinnant584db422012-08-05 21:43:11 +00001039__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
1040 __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001041{
Howard Hinnant584db422012-08-05 21:43:11 +00001042 typedef __bit_iterator<_Cp, _IC1> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001043 typedef typename _It::difference_type difference_type;
1044 typedef typename _It::__storage_type __storage_type;
1045 static const unsigned __bits_per_word = _It::__bits_per_word;
1046 difference_type __n = __last1 - __first1;
1047 if (__n > 0)
1048 {
1049 // do first word
1050 if (__first1.__ctz_ != 0)
1051 {
1052 unsigned __clz = __bits_per_word - __first1.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +00001053 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001054 __n -= __dn;
1055 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
1056 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
1057 return false;
1058 ++__first2.__seg_;
1059 ++__first1.__seg_;
1060 // __first1.__ctz_ = 0;
1061 // __first2.__ctz_ = 0;
1062 }
1063 // __first1.__ctz_ == 0;
1064 // __first2.__ctz_ == 0;
1065 // do middle words
1066 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
1067 if (*__first2.__seg_ != *__first1.__seg_)
1068 return false;
1069 // do last word
1070 if (__n > 0)
1071 {
1072 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
1073 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
1074 return false;
1075 }
1076 }
1077 return true;
1078}
1079
Howard Hinnant99968442011-11-29 18:15:50 +00001080template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001081inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001082bool
Howard Hinnant99968442011-11-29 18:15:50 +00001083equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001084{
1085 if (__first1.__ctz_ == __first2.__ctz_)
1086 return __equal_aligned(__first1, __last1, __first2);
1087 return __equal_unaligned(__first1, __last1, __first2);
1088}
1089
Howard Hinnantf867f632012-05-07 16:50:38 +00001090template <class _Cp, bool _IsConst,
1091 typename _Cp::__storage_type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001092class __bit_iterator
1093{
1094public:
Howard Hinnant99968442011-11-29 18:15:50 +00001095 typedef typename _Cp::difference_type difference_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001096 typedef bool value_type;
1097 typedef __bit_iterator pointer;
Howard Hinnant99968442011-11-29 18:15:50 +00001098 typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001099 typedef random_access_iterator_tag iterator_category;
1100
1101private:
Howard Hinnant99968442011-11-29 18:15:50 +00001102 typedef typename _Cp::__storage_type __storage_type;
1103 typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer,
1104 typename _Cp::__storage_pointer>::type __storage_pointer;
1105 static const unsigned __bits_per_word = _Cp::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001106
1107 __storage_pointer __seg_;
1108 unsigned __ctz_;
1109
1110public:
Marshall Clowb92ee612013-08-07 20:53:44 +00001111 _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
1112#if _LIBCPP_STD_VER > 11
1113 : __seg_(nullptr), __ctz_(0)
1114#endif
1115 {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001116
Howard Hinnant10f25d22011-05-27 20:52:28 +00001117 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001118 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001119 : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
1120
Howard Hinnant10f25d22011-05-27 20:52:28 +00001121 _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
1122 {return reference(__seg_, __storage_type(1) << __ctz_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001123
1124 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()
1125 {
1126 if (__ctz_ != __bits_per_word-1)
1127 ++__ctz_;
1128 else
1129 {
1130 __ctz_ = 0;
1131 ++__seg_;
1132 }
1133 return *this;
1134 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001135
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001136 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int)
1137 {
1138 __bit_iterator __tmp = *this;
1139 ++(*this);
1140 return __tmp;
1141 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001142
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001143 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--()
1144 {
1145 if (__ctz_ != 0)
1146 --__ctz_;
1147 else
1148 {
1149 __ctz_ = __bits_per_word - 1;
1150 --__seg_;
1151 }
1152 return *this;
1153 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001154
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001155 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int)
1156 {
1157 __bit_iterator __tmp = *this;
1158 --(*this);
1159 return __tmp;
1160 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001161
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001162 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n)
1163 {
1164 if (__n >= 0)
1165 __seg_ += (__n + __ctz_) / __bits_per_word;
1166 else
1167 __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1)
1168 / static_cast<difference_type>(__bits_per_word);
1169 __n &= (__bits_per_word - 1);
1170 __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word);
1171 return *this;
1172 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001173
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001174 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n)
1175 {
1176 return *this += -__n;
1177 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001178
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001179 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const
1180 {
1181 __bit_iterator __t(*this);
1182 __t += __n;
1183 return __t;
1184 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001185
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001186 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const
1187 {
1188 __bit_iterator __t(*this);
1189 __t -= __n;
1190 return __t;
1191 }
1192
1193 _LIBCPP_INLINE_VISIBILITY
1194 friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}
1195
1196 _LIBCPP_INLINE_VISIBILITY
1197 friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)
1198 {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}
1199
1200 _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);}
1201
1202 _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
1203 {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}
1204
1205 _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
1206 {return !(__x == __y);}
1207
1208 _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
1209 {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}
1210
1211 _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
1212 {return __y < __x;}
1213
1214 _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)
1215 {return !(__y < __x);}
1216
1217 _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)
1218 {return !(__x < __y);}
1219
1220private:
1221 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant10f25d22011-05-27 20:52:28 +00001222 __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
1223 : __seg_(__s), __ctz_(__ctz) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001224
Marshall Clow0ac5cce2013-10-21 14:29:37 +00001225#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
Howard Hinnant99968442011-11-29 18:15:50 +00001226 friend typename _Cp::__self;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001227#else
Howard Hinnant99968442011-11-29 18:15:50 +00001228 friend class _Cp::__self;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001229#endif
Howard Hinnant99968442011-11-29 18:15:50 +00001230 friend class __bit_reference<_Cp>;
1231 friend class __bit_const_reference<_Cp>;
1232 friend class __bit_iterator<_Cp, true>;
1233 template <class _Dp> friend struct __bit_array;
1234 template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1235 template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1236 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
1237 __bit_iterator<_Dp, _IC> __last,
1238 __bit_iterator<_Dp, false> __result);
1239 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,
1240 __bit_iterator<_Dp, _IC> __last,
1241 __bit_iterator<_Dp, false> __result);
1242 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,
1243 __bit_iterator<_Dp, _IC> __last,
1244 __bit_iterator<_Dp, false> __result);
1245 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first,
1246 __bit_iterator<_Dp, _IC> __last,
1247 __bit_iterator<_Dp, false> __result);
1248 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first,
1249 __bit_iterator<_Dp, _IC> __last,
1250 __bit_iterator<_Dp, false> __result);
1251 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
1252 __bit_iterator<_Dp, _IC> __last,
1253 __bit_iterator<_Dp, false> __result);
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00001254 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
1255 __bit_iterator<__C1, false>,
1256 __bit_iterator<__C2, false>);
1257 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,
1258 __bit_iterator<__C1, false>,
1259 __bit_iterator<__C2, false>);
1260 template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
1261 __bit_iterator<__C1, false>,
1262 __bit_iterator<__C2, false>);
Howard Hinnant99968442011-11-29 18:15:50 +00001263 template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
1264 __bit_iterator<_Dp, false>,
1265 __bit_iterator<_Dp, false>);
Howard Hinnant584db422012-08-05 21:43:11 +00001266 template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
1267 __bit_iterator<_Dp, _IC1>,
1268 __bit_iterator<_Dp, _IC2>);
1269 template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
1270 __bit_iterator<_Dp, _IC1>,
1271 __bit_iterator<_Dp, _IC2>);
Howard Hinnant99968442011-11-29 18:15:50 +00001272 template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>,
1273 __bit_iterator<_Dp, _IC1>,
1274 __bit_iterator<_Dp, _IC2>);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +00001275 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>,
Howard Hinnant99968442011-11-29 18:15:50 +00001276 typename _Dp::size_type);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +00001277 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>,
Howard Hinnant99968442011-11-29 18:15:50 +00001278 typename _Dp::size_type);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +00001279 template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1280 __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1281 template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1282 __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001283};
1284
1285_LIBCPP_END_NAMESPACE_STD
1286
1287#endif // _LIBCPP___BIT_REFERENCE