13e519524SHoward Hinnant// -*- C++ -*- 23e519524SHoward Hinnant//===----------------------------------------------------------------------===// 33e519524SHoward Hinnant// 45b08a8a4SHoward Hinnant// The LLVM Compiler Infrastructure 53e519524SHoward Hinnant// 6412dbebeSHoward Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 7412dbebeSHoward Hinnant// Source Licenses. See LICENSE.TXT for details. 83e519524SHoward Hinnant// 93e519524SHoward Hinnant//===----------------------------------------------------------------------===// 103e519524SHoward Hinnant 113e519524SHoward Hinnant#ifndef _LIBCPP___BIT_REFERENCE 123e519524SHoward Hinnant#define _LIBCPP___BIT_REFERENCE 133e519524SHoward Hinnant 143e519524SHoward Hinnant#include <__config> 15*ecb7f4daSMarshall Clow#include <bit> 163e519524SHoward Hinnant#include <algorithm> 173e519524SHoward Hinnant 18073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 193e519524SHoward Hinnant#pragma GCC system_header 20073458b1SHoward Hinnant#endif 213e519524SHoward Hinnant 22a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS 23a016efb1SEric Fiselier#include <__undef_macros> 24a016efb1SEric Fiselier 25a016efb1SEric Fiselier 263e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 273e519524SHoward Hinnant 280ae9efebSHoward Hinnanttemplate <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator; 29c003db1fSHoward Hinnanttemplate <class _Cp> class __bit_const_reference; 303e519524SHoward Hinnant 31a7744562SHoward Hinnanttemplate <class _Tp> 32a7744562SHoward Hinnantstruct __has_storage_type 33a7744562SHoward Hinnant{ 34a7744562SHoward Hinnant static const bool value = false; 35a7744562SHoward Hinnant}; 36a7744562SHoward Hinnant 37c003db1fSHoward Hinnanttemplate <class _Cp, bool = __has_storage_type<_Cp>::value> 383e519524SHoward Hinnantclass __bit_reference 393e519524SHoward Hinnant{ 40c003db1fSHoward Hinnant typedef typename _Cp::__storage_type __storage_type; 41c003db1fSHoward Hinnant typedef typename _Cp::__storage_pointer __storage_pointer; 423e519524SHoward Hinnant 433e519524SHoward Hinnant __storage_pointer __seg_; 443e519524SHoward Hinnant __storage_type __mask_; 453e519524SHoward Hinnant 46c003db1fSHoward Hinnant friend typename _Cp::__self; 47541f9e28SEric Fiselier 48c003db1fSHoward Hinnant friend class __bit_const_reference<_Cp>; 49c003db1fSHoward Hinnant friend class __bit_iterator<_Cp, false>; 503e519524SHoward Hinnantpublic: 51d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT 52d368a84cSHoward Hinnant {return static_cast<bool>(*__seg_ & __mask_);} 53d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT 54d368a84cSHoward Hinnant {return !static_cast<bool>(*this);} 553e519524SHoward Hinnant 563e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 57d368a84cSHoward Hinnant __bit_reference& operator=(bool __x) _NOEXCEPT 583e519524SHoward Hinnant { 593e519524SHoward Hinnant if (__x) 603e519524SHoward Hinnant *__seg_ |= __mask_; 613e519524SHoward Hinnant else 623e519524SHoward Hinnant *__seg_ &= ~__mask_; 633e519524SHoward Hinnant return *this; 643e519524SHoward Hinnant } 653e519524SHoward Hinnant 663e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 67d368a84cSHoward Hinnant __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT 68d368a84cSHoward Hinnant {return operator=(static_cast<bool>(__x));} 693e519524SHoward Hinnant 70d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;} 71c003db1fSHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT 72c003db1fSHoward Hinnant {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__ctz(__mask_)));} 733e519524SHoward Hinnantprivate: 743e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 75d368a84cSHoward Hinnant __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 76d368a84cSHoward Hinnant : __seg_(__s), __mask_(__m) {} 773e519524SHoward Hinnant}; 783e519524SHoward Hinnant 79c003db1fSHoward Hinnanttemplate <class _Cp> 80c003db1fSHoward Hinnantclass __bit_reference<_Cp, false> 81a7744562SHoward Hinnant{ 82a7744562SHoward Hinnant}; 83a7744562SHoward Hinnant 84d9db9f90SHoward Hinnanttemplate <class _Cp> 853af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 86d9db9f90SHoward Hinnantvoid 87d9db9f90SHoward Hinnantswap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT 88d9db9f90SHoward Hinnant{ 89d9db9f90SHoward Hinnant bool __t = __x; 90d9db9f90SHoward Hinnant __x = __y; 91d9db9f90SHoward Hinnant __y = __t; 92d9db9f90SHoward Hinnant} 93d9db9f90SHoward Hinnant 94c003db1fSHoward Hinnanttemplate <class _Cp, class _Dp> 953af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 963e519524SHoward Hinnantvoid 97c003db1fSHoward Hinnantswap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT 983e519524SHoward Hinnant{ 993e519524SHoward Hinnant bool __t = __x; 1003e519524SHoward Hinnant __x = __y; 1013e519524SHoward Hinnant __y = __t; 1023e519524SHoward Hinnant} 1033e519524SHoward Hinnant 104c003db1fSHoward Hinnanttemplate <class _Cp> 1053af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1063e519524SHoward Hinnantvoid 107c003db1fSHoward Hinnantswap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT 1083e519524SHoward Hinnant{ 1093e519524SHoward Hinnant bool __t = __x; 1103e519524SHoward Hinnant __x = __y; 1113e519524SHoward Hinnant __y = __t; 1123e519524SHoward Hinnant} 1133e519524SHoward Hinnant 114c003db1fSHoward Hinnanttemplate <class _Cp> 1153af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 1163e519524SHoward Hinnantvoid 117c003db1fSHoward Hinnantswap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT 1183e519524SHoward Hinnant{ 1193e519524SHoward Hinnant bool __t = __x; 1203e519524SHoward Hinnant __x = __y; 1213e519524SHoward Hinnant __y = __t; 1223e519524SHoward Hinnant} 1233e519524SHoward Hinnant 124c003db1fSHoward Hinnanttemplate <class _Cp> 1253e519524SHoward Hinnantclass __bit_const_reference 1263e519524SHoward Hinnant{ 127c003db1fSHoward Hinnant typedef typename _Cp::__storage_type __storage_type; 128c003db1fSHoward Hinnant typedef typename _Cp::__const_storage_pointer __storage_pointer; 1293e519524SHoward Hinnant 1303e519524SHoward Hinnant __storage_pointer __seg_; 1313e519524SHoward Hinnant __storage_type __mask_; 1323e519524SHoward Hinnant 133c003db1fSHoward Hinnant friend typename _Cp::__self; 134c003db1fSHoward Hinnant friend class __bit_iterator<_Cp, true>; 1353e519524SHoward Hinnantpublic: 1363e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 137c003db1fSHoward Hinnant __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT 1383e519524SHoward Hinnant : __seg_(__x.__seg_), __mask_(__x.__mask_) {} 1393e519524SHoward Hinnant 140eeac9fcfSHoward Hinnant _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT 141d368a84cSHoward Hinnant {return static_cast<bool>(*__seg_ & __mask_);} 1423e519524SHoward Hinnant 143c003db1fSHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT 144c003db1fSHoward Hinnant {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__ctz(__mask_)));} 1453e519524SHoward Hinnantprivate: 1463e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 147eeac9fcfSHoward Hinnant _LIBCPP_CONSTEXPR 148d368a84cSHoward Hinnant __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 149d368a84cSHoward Hinnant : __seg_(__s), __mask_(__m) {} 1503e519524SHoward Hinnant 1513e519524SHoward Hinnant __bit_const_reference& operator=(const __bit_const_reference& __x); 1523e519524SHoward Hinnant}; 1533e519524SHoward Hinnant 1543e519524SHoward Hinnant// find 1553e519524SHoward Hinnant 156423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst> 157423a8d77SHoward Hinnant__bit_iterator<_Cp, _IsConst> 158423a8d77SHoward Hinnant__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) 1593e519524SHoward Hinnant{ 160423a8d77SHoward Hinnant typedef __bit_iterator<_Cp, _IsConst> _It; 1613e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 162aec08784SEric Fiselier static const int __bits_per_word = _It::__bits_per_word; 1633e519524SHoward Hinnant // do first partial word 1643e519524SHoward Hinnant if (__first.__ctz_ != 0) 1653e519524SHoward Hinnant { 1663e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 167ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 1683e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 1693e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 1703e519524SHoward Hinnant if (__b) 171ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 172303e27d8SHoward Hinnant if (__n == __dn) 1730fc6e981SMarshall Clow return __first + __n; 1743e519524SHoward Hinnant __n -= __dn; 1753e519524SHoward Hinnant ++__first.__seg_; 1763e519524SHoward Hinnant } 1773e519524SHoward Hinnant // do middle whole words 1783e519524SHoward Hinnant for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 1793e519524SHoward Hinnant if (*__first.__seg_) 180ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(*__first.__seg_))); 1813e519524SHoward Hinnant // do last partial word 1823e519524SHoward Hinnant if (__n > 0) 1833e519524SHoward Hinnant { 1843e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 1853e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 1863e519524SHoward Hinnant if (__b) 187ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 1883e519524SHoward Hinnant } 1893e519524SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(__n)); 1903e519524SHoward Hinnant} 1913e519524SHoward Hinnant 192423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst> 193423a8d77SHoward Hinnant__bit_iterator<_Cp, _IsConst> 194423a8d77SHoward Hinnant__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) 1953e519524SHoward Hinnant{ 196423a8d77SHoward Hinnant typedef __bit_iterator<_Cp, _IsConst> _It; 1973e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 198aec08784SEric Fiselier const int __bits_per_word = _It::__bits_per_word; 1993e519524SHoward Hinnant // do first partial word 2003e519524SHoward Hinnant if (__first.__ctz_ != 0) 2013e519524SHoward Hinnant { 2023e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 203ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 2043e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 205423a8d77SHoward Hinnant __storage_type __b = ~*__first.__seg_ & __m; 2063e519524SHoward Hinnant if (__b) 207ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 208303e27d8SHoward Hinnant if (__n == __dn) 2090fc6e981SMarshall Clow return __first + __n; 2103e519524SHoward Hinnant __n -= __dn; 2113e519524SHoward Hinnant ++__first.__seg_; 2123e519524SHoward Hinnant } 2133e519524SHoward Hinnant // do middle whole words 2143e519524SHoward Hinnant for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 2153e519524SHoward Hinnant { 2163e519524SHoward Hinnant __storage_type __b = ~*__first.__seg_; 2173e519524SHoward Hinnant if (__b) 218ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 2193e519524SHoward Hinnant } 2203e519524SHoward Hinnant // do last partial word 2213e519524SHoward Hinnant if (__n > 0) 2223e519524SHoward Hinnant { 2233e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 224423a8d77SHoward Hinnant __storage_type __b = ~*__first.__seg_ & __m; 2253e519524SHoward Hinnant if (__b) 226ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 2273e519524SHoward Hinnant } 2283e519524SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(__n)); 2293e519524SHoward Hinnant} 2303e519524SHoward Hinnant 231423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst, class _Tp> 2323e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 233423a8d77SHoward Hinnant__bit_iterator<_Cp, _IsConst> 234423a8d77SHoward Hinnantfind(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) 2353e519524SHoward Hinnant{ 236e4383379SHoward Hinnant if (static_cast<bool>(__value_)) 237c003db1fSHoward Hinnant return __find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first)); 238c003db1fSHoward Hinnant return __find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first)); 2393e519524SHoward Hinnant} 2403e519524SHoward Hinnant 2413e519524SHoward Hinnant// count 2423e519524SHoward Hinnant 243423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst> 244423a8d77SHoward Hinnanttypename __bit_iterator<_Cp, _IsConst>::difference_type 245423a8d77SHoward Hinnant__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) 2463e519524SHoward Hinnant{ 247423a8d77SHoward Hinnant typedef __bit_iterator<_Cp, _IsConst> _It; 2483e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 2493e519524SHoward Hinnant typedef typename _It::difference_type difference_type; 250aec08784SEric Fiselier const int __bits_per_word = _It::__bits_per_word; 2513e519524SHoward Hinnant difference_type __r = 0; 2523e519524SHoward Hinnant // do first partial word 2533e519524SHoward Hinnant if (__first.__ctz_ != 0) 2543e519524SHoward Hinnant { 2553e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 256ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 2573e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 258*ecb7f4daSMarshall Clow __r = _VSTD::__popcount(*__first.__seg_ & __m); 2593e519524SHoward Hinnant __n -= __dn; 2603e519524SHoward Hinnant ++__first.__seg_; 2613e519524SHoward Hinnant } 2623e519524SHoward Hinnant // do middle whole words 2633e519524SHoward Hinnant for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 264*ecb7f4daSMarshall Clow __r += _VSTD::__popcount(*__first.__seg_); 2653e519524SHoward Hinnant // do last partial word 2663e519524SHoward Hinnant if (__n > 0) 2673e519524SHoward Hinnant { 2683e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 269*ecb7f4daSMarshall Clow __r += _VSTD::__popcount(*__first.__seg_ & __m); 2703e519524SHoward Hinnant } 2713e519524SHoward Hinnant return __r; 2723e519524SHoward Hinnant} 2733e519524SHoward Hinnant 274423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst> 275423a8d77SHoward Hinnanttypename __bit_iterator<_Cp, _IsConst>::difference_type 276423a8d77SHoward Hinnant__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) 2773e519524SHoward Hinnant{ 278423a8d77SHoward Hinnant typedef __bit_iterator<_Cp, _IsConst> _It; 2793e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 2803e519524SHoward Hinnant typedef typename _It::difference_type difference_type; 281aec08784SEric Fiselier const int __bits_per_word = _It::__bits_per_word; 2823e519524SHoward Hinnant difference_type __r = 0; 2833e519524SHoward Hinnant // do first partial word 2843e519524SHoward Hinnant if (__first.__ctz_ != 0) 2853e519524SHoward Hinnant { 2863e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 287ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 2883e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 289*ecb7f4daSMarshall Clow __r = _VSTD::__popcount(~*__first.__seg_ & __m); 2903e519524SHoward Hinnant __n -= __dn; 2913e519524SHoward Hinnant ++__first.__seg_; 2923e519524SHoward Hinnant } 2933e519524SHoward Hinnant // do middle whole words 2943e519524SHoward Hinnant for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 295*ecb7f4daSMarshall Clow __r += _VSTD::__popcount(~*__first.__seg_); 2963e519524SHoward Hinnant // do last partial word 2973e519524SHoward Hinnant if (__n > 0) 2983e519524SHoward Hinnant { 2993e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 300*ecb7f4daSMarshall Clow __r += _VSTD::__popcount(~*__first.__seg_ & __m); 3013e519524SHoward Hinnant } 3023e519524SHoward Hinnant return __r; 3033e519524SHoward Hinnant} 3043e519524SHoward Hinnant 305423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst, class _Tp> 3063e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 307423a8d77SHoward Hinnanttypename __bit_iterator<_Cp, _IsConst>::difference_type 308423a8d77SHoward Hinnantcount(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_) 3093e519524SHoward Hinnant{ 310e4383379SHoward Hinnant if (static_cast<bool>(__value_)) 311c003db1fSHoward Hinnant return __count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first)); 312c003db1fSHoward Hinnant return __count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first)); 3133e519524SHoward Hinnant} 3143e519524SHoward Hinnant 3153e519524SHoward Hinnant// fill_n 3163e519524SHoward Hinnant 317c003db1fSHoward Hinnanttemplate <class _Cp> 3183e519524SHoward Hinnantvoid 319c003db1fSHoward Hinnant__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) 3203e519524SHoward Hinnant{ 321c003db1fSHoward Hinnant typedef __bit_iterator<_Cp, false> _It; 3223e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 323aec08784SEric Fiselier const int __bits_per_word = _It::__bits_per_word; 3243e519524SHoward Hinnant // do first partial word 3253e519524SHoward Hinnant if (__first.__ctz_ != 0) 3263e519524SHoward Hinnant { 3273e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 328ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 3293e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 3303e519524SHoward Hinnant *__first.__seg_ &= ~__m; 3313e519524SHoward Hinnant __n -= __dn; 3323e519524SHoward Hinnant ++__first.__seg_; 3333e519524SHoward Hinnant } 3343e519524SHoward Hinnant // do middle whole words 3353e519524SHoward Hinnant __storage_type __nw = __n / __bits_per_word; 3363ec1f00bSHoward Hinnant _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type)); 3373e519524SHoward Hinnant __n -= __nw * __bits_per_word; 3383e519524SHoward Hinnant // do last partial word 3393e519524SHoward Hinnant if (__n > 0) 3403e519524SHoward Hinnant { 3413e519524SHoward Hinnant __first.__seg_ += __nw; 3423e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 3433e519524SHoward Hinnant *__first.__seg_ &= ~__m; 3443e519524SHoward Hinnant } 3453e519524SHoward Hinnant} 3463e519524SHoward Hinnant 347c003db1fSHoward Hinnanttemplate <class _Cp> 3483e519524SHoward Hinnantvoid 349c003db1fSHoward Hinnant__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) 3503e519524SHoward Hinnant{ 351c003db1fSHoward Hinnant typedef __bit_iterator<_Cp, false> _It; 3523e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 353aec08784SEric Fiselier const int __bits_per_word = _It::__bits_per_word; 3543e519524SHoward Hinnant // do first partial word 3553e519524SHoward Hinnant if (__first.__ctz_ != 0) 3563e519524SHoward Hinnant { 3573e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 358ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 3593e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 3603e519524SHoward Hinnant *__first.__seg_ |= __m; 3613e519524SHoward Hinnant __n -= __dn; 3623e519524SHoward Hinnant ++__first.__seg_; 3633e519524SHoward Hinnant } 3643e519524SHoward Hinnant // do middle whole words 3653e519524SHoward Hinnant __storage_type __nw = __n / __bits_per_word; 3663ec1f00bSHoward Hinnant _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type)); 3673e519524SHoward Hinnant __n -= __nw * __bits_per_word; 3683e519524SHoward Hinnant // do last partial word 3693e519524SHoward Hinnant if (__n > 0) 3703e519524SHoward Hinnant { 3713e519524SHoward Hinnant __first.__seg_ += __nw; 3723e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 3733e519524SHoward Hinnant *__first.__seg_ |= __m; 3743e519524SHoward Hinnant } 3753e519524SHoward Hinnant} 3763e519524SHoward Hinnant 377c003db1fSHoward Hinnanttemplate <class _Cp> 3783af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 3793e519524SHoward Hinnantvoid 380c003db1fSHoward Hinnantfill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_) 3813e519524SHoward Hinnant{ 3823e519524SHoward Hinnant if (__n > 0) 3833e519524SHoward Hinnant { 384e4383379SHoward Hinnant if (__value_) 3853e519524SHoward Hinnant __fill_n_true(__first, __n); 3863e519524SHoward Hinnant else 3873e519524SHoward Hinnant __fill_n_false(__first, __n); 3883e519524SHoward Hinnant } 3893e519524SHoward Hinnant} 3903e519524SHoward Hinnant 3913e519524SHoward Hinnant// fill 3923e519524SHoward Hinnant 393c003db1fSHoward Hinnanttemplate <class _Cp> 3943e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 3953e519524SHoward Hinnantvoid 396c003db1fSHoward Hinnantfill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_) 3973e519524SHoward Hinnant{ 398c003db1fSHoward Hinnant _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_); 3993e519524SHoward Hinnant} 4003e519524SHoward Hinnant 4013e519524SHoward Hinnant// copy 4023e519524SHoward Hinnant 403c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst> 404c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 405c003db1fSHoward Hinnant__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, 406c003db1fSHoward Hinnant __bit_iterator<_Cp, false> __result) 4073e519524SHoward Hinnant{ 408c003db1fSHoward Hinnant typedef __bit_iterator<_Cp, _IsConst> _In; 4093e519524SHoward Hinnant typedef typename _In::difference_type difference_type; 4103e519524SHoward Hinnant typedef typename _In::__storage_type __storage_type; 411aec08784SEric Fiselier const int __bits_per_word = _In::__bits_per_word; 4123e519524SHoward Hinnant difference_type __n = __last - __first; 4133e519524SHoward Hinnant if (__n > 0) 4143e519524SHoward Hinnant { 4153e519524SHoward Hinnant // do first word 4163e519524SHoward Hinnant if (__first.__ctz_ != 0) 4173e519524SHoward Hinnant { 4183e519524SHoward Hinnant unsigned __clz = __bits_per_word - __first.__ctz_; 419ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 4203e519524SHoward Hinnant __n -= __dn; 4213e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 4223e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 4233e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4243e519524SHoward Hinnant *__result.__seg_ |= __b; 4253e519524SHoward Hinnant __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 4263e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 4273e519524SHoward Hinnant ++__first.__seg_; 4283e519524SHoward Hinnant // __first.__ctz_ = 0; 4293e519524SHoward Hinnant } 4303e519524SHoward Hinnant // __first.__ctz_ == 0; 4313e519524SHoward Hinnant // do middle words 4323e519524SHoward Hinnant __storage_type __nw = __n / __bits_per_word; 4333ec1f00bSHoward Hinnant _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), 4343ec1f00bSHoward Hinnant _VSTD::__to_raw_pointer(__first.__seg_), 4353ec1f00bSHoward Hinnant __nw * sizeof(__storage_type)); 4363e519524SHoward Hinnant __n -= __nw * __bits_per_word; 4373e519524SHoward Hinnant __result.__seg_ += __nw; 4383e519524SHoward Hinnant // do last word 4393e519524SHoward Hinnant if (__n > 0) 4403e519524SHoward Hinnant { 4413e519524SHoward Hinnant __first.__seg_ += __nw; 4423e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 4433e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 4443e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4453e519524SHoward Hinnant *__result.__seg_ |= __b; 4463e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__n); 4473e519524SHoward Hinnant } 4483e519524SHoward Hinnant } 4493e519524SHoward Hinnant return __result; 4503e519524SHoward Hinnant} 4513e519524SHoward Hinnant 452c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst> 453c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 454c003db1fSHoward Hinnant__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, 455c003db1fSHoward Hinnant __bit_iterator<_Cp, false> __result) 4563e519524SHoward Hinnant{ 457c003db1fSHoward Hinnant typedef __bit_iterator<_Cp, _IsConst> _In; 4583e519524SHoward Hinnant typedef typename _In::difference_type difference_type; 4593e519524SHoward Hinnant typedef typename _In::__storage_type __storage_type; 460aec08784SEric Fiselier static const int __bits_per_word = _In::__bits_per_word; 4613e519524SHoward Hinnant difference_type __n = __last - __first; 4623e519524SHoward Hinnant if (__n > 0) 4633e519524SHoward Hinnant { 4643e519524SHoward Hinnant // do first word 4653e519524SHoward Hinnant if (__first.__ctz_ != 0) 4663e519524SHoward Hinnant { 4673e519524SHoward Hinnant unsigned __clz_f = __bits_per_word - __first.__ctz_; 468ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 4693e519524SHoward Hinnant __n -= __dn; 4703e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 4713e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 4723e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 473ce48a113SHoward Hinnant __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 4743e519524SHoward Hinnant __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 4753e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4763e519524SHoward Hinnant if (__result.__ctz_ > __first.__ctz_) 4773e519524SHoward Hinnant *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); 4783e519524SHoward Hinnant else 4793e519524SHoward Hinnant *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); 4803e519524SHoward Hinnant __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; 4813e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); 4823e519524SHoward Hinnant __dn -= __ddn; 4833e519524SHoward Hinnant if (__dn > 0) 4843e519524SHoward Hinnant { 4853e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __dn); 4863e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4873e519524SHoward Hinnant *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); 4883e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__dn); 4893e519524SHoward Hinnant } 4903e519524SHoward Hinnant ++__first.__seg_; 4913e519524SHoward Hinnant // __first.__ctz_ = 0; 4923e519524SHoward Hinnant } 4933e519524SHoward Hinnant // __first.__ctz_ == 0; 4943e519524SHoward Hinnant // do middle words 4953e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 4963e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) << __result.__ctz_; 4973e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) 4983e519524SHoward Hinnant { 4993e519524SHoward Hinnant __storage_type __b = *__first.__seg_; 5003e519524SHoward Hinnant *__result.__seg_ &= ~__m; 5013e519524SHoward Hinnant *__result.__seg_ |= __b << __result.__ctz_; 5023e519524SHoward Hinnant ++__result.__seg_; 5033e519524SHoward Hinnant *__result.__seg_ &= __m; 5043e519524SHoward Hinnant *__result.__seg_ |= __b >> __clz_r; 5053e519524SHoward Hinnant } 5063e519524SHoward Hinnant // do last word 5073e519524SHoward Hinnant if (__n > 0) 5083e519524SHoward Hinnant { 5093e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 5103e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 511ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r)); 5123e519524SHoward Hinnant __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 5133e519524SHoward Hinnant *__result.__seg_ &= ~__m; 5143e519524SHoward Hinnant *__result.__seg_ |= __b << __result.__ctz_; 5153e519524SHoward Hinnant __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 5163e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 5173e519524SHoward Hinnant __n -= __dn; 5183e519524SHoward Hinnant if (__n > 0) 5193e519524SHoward Hinnant { 5203e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 5213e519524SHoward Hinnant *__result.__seg_ &= ~__m; 5223e519524SHoward Hinnant *__result.__seg_ |= __b >> __dn; 5233e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__n); 5243e519524SHoward Hinnant } 5253e519524SHoward Hinnant } 5263e519524SHoward Hinnant } 5273e519524SHoward Hinnant return __result; 5283e519524SHoward Hinnant} 5293e519524SHoward Hinnant 530c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst> 5313e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 532c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 533c003db1fSHoward Hinnantcopy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) 5343e519524SHoward Hinnant{ 5353e519524SHoward Hinnant if (__first.__ctz_ == __result.__ctz_) 5363e519524SHoward Hinnant return __copy_aligned(__first, __last, __result); 5373e519524SHoward Hinnant return __copy_unaligned(__first, __last, __result); 5383e519524SHoward Hinnant} 5393e519524SHoward Hinnant 5403e519524SHoward Hinnant// copy_backward 5413e519524SHoward Hinnant 542c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst> 543c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 544c003db1fSHoward Hinnant__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, 545c003db1fSHoward Hinnant __bit_iterator<_Cp, false> __result) 5463e519524SHoward Hinnant{ 547c003db1fSHoward Hinnant typedef __bit_iterator<_Cp, _IsConst> _In; 5483e519524SHoward Hinnant typedef typename _In::difference_type difference_type; 5493e519524SHoward Hinnant typedef typename _In::__storage_type __storage_type; 550aec08784SEric Fiselier const int __bits_per_word = _In::__bits_per_word; 5513e519524SHoward Hinnant difference_type __n = __last - __first; 5523e519524SHoward Hinnant if (__n > 0) 5533e519524SHoward Hinnant { 5543e519524SHoward Hinnant // do first word 5553e519524SHoward Hinnant if (__last.__ctz_ != 0) 5563e519524SHoward Hinnant { 557ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n); 5583e519524SHoward Hinnant __n -= __dn; 5593e519524SHoward Hinnant unsigned __clz = __bits_per_word - __last.__ctz_; 5603e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); 5613e519524SHoward Hinnant __storage_type __b = *__last.__seg_ & __m; 5623e519524SHoward Hinnant *__result.__seg_ &= ~__m; 5633e519524SHoward Hinnant *__result.__seg_ |= __b; 5643e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + 5653e519524SHoward Hinnant __result.__ctz_) % __bits_per_word); 5663e519524SHoward Hinnant // __last.__ctz_ = 0 5673e519524SHoward Hinnant } 5683e519524SHoward Hinnant // __last.__ctz_ == 0 || __n == 0 5693e519524SHoward Hinnant // __result.__ctz_ == 0 || __n == 0 5703e519524SHoward Hinnant // do middle words 5713e519524SHoward Hinnant __storage_type __nw = __n / __bits_per_word; 5723e519524SHoward Hinnant __result.__seg_ -= __nw; 5733e519524SHoward Hinnant __last.__seg_ -= __nw; 5743ec1f00bSHoward Hinnant _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), 5753ec1f00bSHoward Hinnant _VSTD::__to_raw_pointer(__last.__seg_), 5763ec1f00bSHoward Hinnant __nw * sizeof(__storage_type)); 5773e519524SHoward Hinnant __n -= __nw * __bits_per_word; 5783e519524SHoward Hinnant // do last word 5793e519524SHoward Hinnant if (__n > 0) 5803e519524SHoward Hinnant { 5813e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); 5823e519524SHoward Hinnant __storage_type __b = *--__last.__seg_ & __m; 5833e519524SHoward Hinnant *--__result.__seg_ &= ~__m; 5843e519524SHoward Hinnant *__result.__seg_ |= __b; 5853e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); 5863e519524SHoward Hinnant } 5873e519524SHoward Hinnant } 5883e519524SHoward Hinnant return __result; 5893e519524SHoward Hinnant} 5903e519524SHoward Hinnant 591c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst> 592c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 593c003db1fSHoward Hinnant__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, 594c003db1fSHoward Hinnant __bit_iterator<_Cp, false> __result) 5953e519524SHoward Hinnant{ 596c003db1fSHoward Hinnant typedef __bit_iterator<_Cp, _IsConst> _In; 5973e519524SHoward Hinnant typedef typename _In::difference_type difference_type; 5983e519524SHoward Hinnant typedef typename _In::__storage_type __storage_type; 599aec08784SEric Fiselier const int __bits_per_word = _In::__bits_per_word; 6003e519524SHoward Hinnant difference_type __n = __last - __first; 6013e519524SHoward Hinnant if (__n > 0) 6023e519524SHoward Hinnant { 6033e519524SHoward Hinnant // do first word 6043e519524SHoward Hinnant if (__last.__ctz_ != 0) 6053e519524SHoward Hinnant { 606ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n); 6073e519524SHoward Hinnant __n -= __dn; 6083e519524SHoward Hinnant unsigned __clz_l = __bits_per_word - __last.__ctz_; 6093e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); 6103e519524SHoward Hinnant __storage_type __b = *__last.__seg_ & __m; 6113e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 612ce48a113SHoward Hinnant __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_)); 6133e519524SHoward Hinnant if (__ddn > 0) 6143e519524SHoward Hinnant { 6153e519524SHoward Hinnant __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); 6163e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6173e519524SHoward Hinnant if (__result.__ctz_ > __last.__ctz_) 6183e519524SHoward Hinnant *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); 6193e519524SHoward Hinnant else 6203e519524SHoward Hinnant *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); 6213e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + 6223e519524SHoward Hinnant __result.__ctz_) % __bits_per_word); 6233e519524SHoward Hinnant __dn -= __ddn; 6243e519524SHoward Hinnant } 6253e519524SHoward Hinnant if (__dn > 0) 6263e519524SHoward Hinnant { 6273e519524SHoward Hinnant // __result.__ctz_ == 0 6283e519524SHoward Hinnant --__result.__seg_; 6293e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1)); 6303e519524SHoward Hinnant __m = ~__storage_type(0) << __result.__ctz_; 6313e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6323e519524SHoward Hinnant __last.__ctz_ -= __dn + __ddn; 6333e519524SHoward Hinnant *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); 6343e519524SHoward Hinnant } 6353e519524SHoward Hinnant // __last.__ctz_ = 0 6363e519524SHoward Hinnant } 6373e519524SHoward Hinnant // __last.__ctz_ == 0 || __n == 0 6383e519524SHoward Hinnant // __result.__ctz_ != 0 || __n == 0 6393e519524SHoward Hinnant // do middle words 6403e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 6413e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> __clz_r; 6423e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word) 6433e519524SHoward Hinnant { 6443e519524SHoward Hinnant __storage_type __b = *--__last.__seg_; 6453e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6463e519524SHoward Hinnant *__result.__seg_ |= __b >> __clz_r; 6473e519524SHoward Hinnant *--__result.__seg_ &= __m; 6483e519524SHoward Hinnant *__result.__seg_ |= __b << __result.__ctz_; 6493e519524SHoward Hinnant } 6503e519524SHoward Hinnant // do last word 6513e519524SHoward Hinnant if (__n > 0) 6523e519524SHoward Hinnant { 6533e519524SHoward Hinnant __m = ~__storage_type(0) << (__bits_per_word - __n); 6543e519524SHoward Hinnant __storage_type __b = *--__last.__seg_ & __m; 655c206366fSHoward Hinnant __clz_r = __bits_per_word - __result.__ctz_; 656ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_)); 6573e519524SHoward Hinnant __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); 6583e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6593e519524SHoward Hinnant *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); 6603e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + 6613e519524SHoward Hinnant __result.__ctz_) % __bits_per_word); 6623e519524SHoward Hinnant __n -= __dn; 6633e519524SHoward Hinnant if (__n > 0) 6643e519524SHoward Hinnant { 6653e519524SHoward Hinnant // __result.__ctz_ == 0 6663e519524SHoward Hinnant --__result.__seg_; 6673e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); 6683e519524SHoward Hinnant __m = ~__storage_type(0) << __result.__ctz_; 6693e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6703e519524SHoward Hinnant *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); 6713e519524SHoward Hinnant } 6723e519524SHoward Hinnant } 6733e519524SHoward Hinnant } 6743e519524SHoward Hinnant return __result; 6753e519524SHoward Hinnant} 6763e519524SHoward Hinnant 677c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst> 6783e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 679c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 680c003db1fSHoward Hinnantcopy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) 6813e519524SHoward Hinnant{ 6823e519524SHoward Hinnant if (__last.__ctz_ == __result.__ctz_) 6833e519524SHoward Hinnant return __copy_backward_aligned(__first, __last, __result); 6843e519524SHoward Hinnant return __copy_backward_unaligned(__first, __last, __result); 6853e519524SHoward Hinnant} 6863e519524SHoward Hinnant 6873e519524SHoward Hinnant// move 6883e519524SHoward Hinnant 689c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst> 6903e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 691c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 692c003db1fSHoward Hinnantmove(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) 6933e519524SHoward Hinnant{ 694ce48a113SHoward Hinnant return _VSTD::copy(__first, __last, __result); 6953e519524SHoward Hinnant} 6963e519524SHoward Hinnant 6973e519524SHoward Hinnant// move_backward 6983e519524SHoward Hinnant 699c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst> 7003e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 701c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 702c003db1fSHoward Hinnantmove_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) 7033e519524SHoward Hinnant{ 70408de4b0dSMarshall Clow return _VSTD::copy_backward(__first, __last, __result); 7053e519524SHoward Hinnant} 7063e519524SHoward Hinnant 7073e519524SHoward Hinnant// swap_ranges 7083e519524SHoward Hinnant 709dbe81119SHoward Hinnanttemplate <class __C1, class __C2> 710dbe81119SHoward Hinnant__bit_iterator<__C2, false> 711dbe81119SHoward Hinnant__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, 712dbe81119SHoward Hinnant __bit_iterator<__C2, false> __result) 7133e519524SHoward Hinnant{ 714dbe81119SHoward Hinnant typedef __bit_iterator<__C1, false> _I1; 7153e519524SHoward Hinnant typedef typename _I1::difference_type difference_type; 7163e519524SHoward Hinnant typedef typename _I1::__storage_type __storage_type; 717aec08784SEric Fiselier const int __bits_per_word = _I1::__bits_per_word; 7183e519524SHoward Hinnant difference_type __n = __last - __first; 7193e519524SHoward Hinnant if (__n > 0) 7203e519524SHoward Hinnant { 7213e519524SHoward Hinnant // do first word 7223e519524SHoward Hinnant if (__first.__ctz_ != 0) 7233e519524SHoward Hinnant { 7243e519524SHoward Hinnant unsigned __clz = __bits_per_word - __first.__ctz_; 725ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 7263e519524SHoward Hinnant __n -= __dn; 7273e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 7283e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_ & __m; 7293e519524SHoward Hinnant *__first.__seg_ &= ~__m; 7303e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 7313e519524SHoward Hinnant *__result.__seg_ &= ~__m; 7323e519524SHoward Hinnant *__result.__seg_ |= __b1; 7333e519524SHoward Hinnant *__first.__seg_ |= __b2; 7343e519524SHoward Hinnant __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 7353e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 7363e519524SHoward Hinnant ++__first.__seg_; 7373e519524SHoward Hinnant // __first.__ctz_ = 0; 7383e519524SHoward Hinnant } 7393e519524SHoward Hinnant // __first.__ctz_ == 0; 7403e519524SHoward Hinnant // do middle words 7413e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) 7423e519524SHoward Hinnant swap(*__first.__seg_, *__result.__seg_); 7433e519524SHoward Hinnant // do last word 7443e519524SHoward Hinnant if (__n > 0) 7453e519524SHoward Hinnant { 7463e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 7473e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_ & __m; 7483e519524SHoward Hinnant *__first.__seg_ &= ~__m; 7493e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 7503e519524SHoward Hinnant *__result.__seg_ &= ~__m; 7513e519524SHoward Hinnant *__result.__seg_ |= __b1; 7523e519524SHoward Hinnant *__first.__seg_ |= __b2; 7533e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__n); 7543e519524SHoward Hinnant } 7553e519524SHoward Hinnant } 7563e519524SHoward Hinnant return __result; 7573e519524SHoward Hinnant} 7583e519524SHoward Hinnant 759dbe81119SHoward Hinnanttemplate <class __C1, class __C2> 760dbe81119SHoward Hinnant__bit_iterator<__C2, false> 761dbe81119SHoward Hinnant__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, 762dbe81119SHoward Hinnant __bit_iterator<__C2, false> __result) 7633e519524SHoward Hinnant{ 764dbe81119SHoward Hinnant typedef __bit_iterator<__C1, false> _I1; 7653e519524SHoward Hinnant typedef typename _I1::difference_type difference_type; 7663e519524SHoward Hinnant typedef typename _I1::__storage_type __storage_type; 767aec08784SEric Fiselier const int __bits_per_word = _I1::__bits_per_word; 7683e519524SHoward Hinnant difference_type __n = __last - __first; 7693e519524SHoward Hinnant if (__n > 0) 7703e519524SHoward Hinnant { 7713e519524SHoward Hinnant // do first word 7723e519524SHoward Hinnant if (__first.__ctz_ != 0) 7733e519524SHoward Hinnant { 7743e519524SHoward Hinnant unsigned __clz_f = __bits_per_word - __first.__ctz_; 775ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 7763e519524SHoward Hinnant __n -= __dn; 7773e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 7783e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_ & __m; 7793e519524SHoward Hinnant *__first.__seg_ &= ~__m; 7803e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 781ce48a113SHoward Hinnant __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 7823e519524SHoward Hinnant __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 7833e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 7843e519524SHoward Hinnant *__result.__seg_ &= ~__m; 7853e519524SHoward Hinnant if (__result.__ctz_ > __first.__ctz_) 7863e519524SHoward Hinnant { 7873e519524SHoward Hinnant unsigned __s = __result.__ctz_ - __first.__ctz_; 7883e519524SHoward Hinnant *__result.__seg_ |= __b1 << __s; 7893e519524SHoward Hinnant *__first.__seg_ |= __b2 >> __s; 7903e519524SHoward Hinnant } 7913e519524SHoward Hinnant else 7923e519524SHoward Hinnant { 7933e519524SHoward Hinnant unsigned __s = __first.__ctz_ - __result.__ctz_; 7943e519524SHoward Hinnant *__result.__seg_ |= __b1 >> __s; 7953e519524SHoward Hinnant *__first.__seg_ |= __b2 << __s; 7963e519524SHoward Hinnant } 7973e519524SHoward Hinnant __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; 7983e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); 7993e519524SHoward Hinnant __dn -= __ddn; 8003e519524SHoward Hinnant if (__dn > 0) 8013e519524SHoward Hinnant { 8023e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __dn); 8033e519524SHoward Hinnant __b2 = *__result.__seg_ & __m; 8043e519524SHoward Hinnant *__result.__seg_ &= ~__m; 8053e519524SHoward Hinnant unsigned __s = __first.__ctz_ + __ddn; 8063e519524SHoward Hinnant *__result.__seg_ |= __b1 >> __s; 8073e519524SHoward Hinnant *__first.__seg_ |= __b2 << __s; 8083e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__dn); 8093e519524SHoward Hinnant } 8103e519524SHoward Hinnant ++__first.__seg_; 8113e519524SHoward Hinnant // __first.__ctz_ = 0; 8123e519524SHoward Hinnant } 8133e519524SHoward Hinnant // __first.__ctz_ == 0; 8143e519524SHoward Hinnant // do middle words 8153e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) << __result.__ctz_; 8163e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 8173e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) 8183e519524SHoward Hinnant { 8193e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_; 8203e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 8213e519524SHoward Hinnant *__result.__seg_ &= ~__m; 8223e519524SHoward Hinnant *__result.__seg_ |= __b1 << __result.__ctz_; 8233e519524SHoward Hinnant *__first.__seg_ = __b2 >> __result.__ctz_; 8243e519524SHoward Hinnant ++__result.__seg_; 8253e519524SHoward Hinnant __b2 = *__result.__seg_ & ~__m; 8263e519524SHoward Hinnant *__result.__seg_ &= __m; 8273e519524SHoward Hinnant *__result.__seg_ |= __b1 >> __clz_r; 8283e519524SHoward Hinnant *__first.__seg_ |= __b2 << __clz_r; 8293e519524SHoward Hinnant } 8303e519524SHoward Hinnant // do last word 8313e519524SHoward Hinnant if (__n > 0) 8323e519524SHoward Hinnant { 8333e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 8343e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_ & __m; 8353e519524SHoward Hinnant *__first.__seg_ &= ~__m; 836ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r); 8373e519524SHoward Hinnant __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 8383e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 8393e519524SHoward Hinnant *__result.__seg_ &= ~__m; 8403e519524SHoward Hinnant *__result.__seg_ |= __b1 << __result.__ctz_; 8413e519524SHoward Hinnant *__first.__seg_ |= __b2 >> __result.__ctz_; 8423e519524SHoward Hinnant __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 8433e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 8443e519524SHoward Hinnant __n -= __dn; 8453e519524SHoward Hinnant if (__n > 0) 8463e519524SHoward Hinnant { 8473e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 8483e519524SHoward Hinnant __b2 = *__result.__seg_ & __m; 8493e519524SHoward Hinnant *__result.__seg_ &= ~__m; 8503e519524SHoward Hinnant *__result.__seg_ |= __b1 >> __dn; 8513e519524SHoward Hinnant *__first.__seg_ |= __b2 << __dn; 8523e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__n); 8533e519524SHoward Hinnant } 8543e519524SHoward Hinnant } 8553e519524SHoward Hinnant } 8563e519524SHoward Hinnant return __result; 8573e519524SHoward Hinnant} 8583e519524SHoward Hinnant 859dbe81119SHoward Hinnanttemplate <class __C1, class __C2> 8603e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 861dbe81119SHoward Hinnant__bit_iterator<__C2, false> 862dbe81119SHoward Hinnantswap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, 863dbe81119SHoward Hinnant __bit_iterator<__C2, false> __first2) 8643e519524SHoward Hinnant{ 8653e519524SHoward Hinnant if (__first1.__ctz_ == __first2.__ctz_) 8663e519524SHoward Hinnant return __swap_ranges_aligned(__first1, __last1, __first2); 8673e519524SHoward Hinnant return __swap_ranges_unaligned(__first1, __last1, __first2); 8683e519524SHoward Hinnant} 8693e519524SHoward Hinnant 8703e519524SHoward Hinnant// rotate 8713e519524SHoward Hinnant 872c003db1fSHoward Hinnanttemplate <class _Cp> 8733e519524SHoward Hinnantstruct __bit_array 8743e519524SHoward Hinnant{ 875c003db1fSHoward Hinnant typedef typename _Cp::difference_type difference_type; 876c003db1fSHoward Hinnant typedef typename _Cp::__storage_type __storage_type; 8773ec1f00bSHoward Hinnant typedef typename _Cp::__storage_pointer __storage_pointer; 878c003db1fSHoward Hinnant typedef typename _Cp::iterator iterator; 879c003db1fSHoward Hinnant static const unsigned __bits_per_word = _Cp::__bits_per_word; 880c003db1fSHoward Hinnant static const unsigned _Np = 4; 8813e519524SHoward Hinnant 8823e519524SHoward Hinnant difference_type __size_; 883c003db1fSHoward Hinnant __storage_type __word_[_Np]; 8843e519524SHoward Hinnant 8853e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY static difference_type capacity() 886c003db1fSHoward Hinnant {return static_cast<difference_type>(_Np * __bits_per_word);} 8873e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {} 8883ec1f00bSHoward Hinnant _LIBCPP_INLINE_VISIBILITY iterator begin() 8893ec1f00bSHoward Hinnant { 8903ec1f00bSHoward Hinnant return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); 8913ec1f00bSHoward Hinnant } 8923ec1f00bSHoward Hinnant _LIBCPP_INLINE_VISIBILITY iterator end() 8933ec1f00bSHoward Hinnant { 8943ec1f00bSHoward Hinnant return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, 8953ec1f00bSHoward Hinnant static_cast<unsigned>(__size_ % __bits_per_word)); 8963ec1f00bSHoward Hinnant } 8973e519524SHoward Hinnant}; 8983e519524SHoward Hinnant 899c003db1fSHoward Hinnanttemplate <class _Cp> 900c003db1fSHoward Hinnant__bit_iterator<_Cp, false> 901c003db1fSHoward Hinnantrotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) 9023e519524SHoward Hinnant{ 903c003db1fSHoward Hinnant typedef __bit_iterator<_Cp, false> _I1; 9043e519524SHoward Hinnant typedef typename _I1::difference_type difference_type; 9053e519524SHoward Hinnant difference_type __d1 = __middle - __first; 9063e519524SHoward Hinnant difference_type __d2 = __last - __middle; 9073e519524SHoward Hinnant _I1 __r = __first + __d2; 9083e519524SHoward Hinnant while (__d1 != 0 && __d2 != 0) 9093e519524SHoward Hinnant { 9103e519524SHoward Hinnant if (__d1 <= __d2) 9113e519524SHoward Hinnant { 912c003db1fSHoward Hinnant if (__d1 <= __bit_array<_Cp>::capacity()) 9133e519524SHoward Hinnant { 914c003db1fSHoward Hinnant __bit_array<_Cp> __b(__d1); 915ce48a113SHoward Hinnant _VSTD::copy(__first, __middle, __b.begin()); 916ce48a113SHoward Hinnant _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first)); 9173e519524SHoward Hinnant break; 9183e519524SHoward Hinnant } 9193e519524SHoward Hinnant else 9203e519524SHoward Hinnant { 921c003db1fSHoward Hinnant __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle); 9223e519524SHoward Hinnant __first = __middle; 9233e519524SHoward Hinnant __middle = __mp; 9243e519524SHoward Hinnant __d2 -= __d1; 9253e519524SHoward Hinnant } 9263e519524SHoward Hinnant } 9273e519524SHoward Hinnant else 9283e519524SHoward Hinnant { 929c003db1fSHoward Hinnant if (__d2 <= __bit_array<_Cp>::capacity()) 9303e519524SHoward Hinnant { 931c003db1fSHoward Hinnant __bit_array<_Cp> __b(__d2); 932ce48a113SHoward Hinnant _VSTD::copy(__middle, __last, __b.begin()); 933ce48a113SHoward Hinnant _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last)); 9343e519524SHoward Hinnant break; 9353e519524SHoward Hinnant } 9363e519524SHoward Hinnant else 9373e519524SHoward Hinnant { 938c003db1fSHoward Hinnant __bit_iterator<_Cp, false> __mp = __first + __d2; 939ce48a113SHoward Hinnant _VSTD::swap_ranges(__first, __mp, __middle); 9403e519524SHoward Hinnant __first = __mp; 9413e519524SHoward Hinnant __d1 -= __d2; 9423e519524SHoward Hinnant } 9433e519524SHoward Hinnant } 9443e519524SHoward Hinnant } 9453e519524SHoward Hinnant return __r; 9463e519524SHoward Hinnant} 9473e519524SHoward Hinnant 9483e519524SHoward Hinnant// equal 9493e519524SHoward Hinnant 9501237dccaSHoward Hinnanttemplate <class _Cp, bool _IC1, bool _IC2> 9513e519524SHoward Hinnantbool 9521237dccaSHoward Hinnant__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, 9531237dccaSHoward Hinnant __bit_iterator<_Cp, _IC2> __first2) 9543e519524SHoward Hinnant{ 9551237dccaSHoward Hinnant typedef __bit_iterator<_Cp, _IC1> _It; 9563e519524SHoward Hinnant typedef typename _It::difference_type difference_type; 9573e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 958aec08784SEric Fiselier static const int __bits_per_word = _It::__bits_per_word; 9593e519524SHoward Hinnant difference_type __n = __last1 - __first1; 9603e519524SHoward Hinnant if (__n > 0) 9613e519524SHoward Hinnant { 9623e519524SHoward Hinnant // do first word 9633e519524SHoward Hinnant if (__first1.__ctz_ != 0) 9643e519524SHoward Hinnant { 9653e519524SHoward Hinnant unsigned __clz_f = __bits_per_word - __first1.__ctz_; 966ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 9673e519524SHoward Hinnant __n -= __dn; 9683e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 9693e519524SHoward Hinnant __storage_type __b = *__first1.__seg_ & __m; 9703e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __first2.__ctz_; 971ce48a113SHoward Hinnant __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 9723e519524SHoward Hinnant __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 9733e519524SHoward Hinnant if (__first2.__ctz_ > __first1.__ctz_) 9744c0de496SHoward Hinnant { 9753e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) 9763e519524SHoward Hinnant return false; 9774c0de496SHoward Hinnant } 9783e519524SHoward Hinnant else 9794c0de496SHoward Hinnant { 9803e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) 9813e519524SHoward Hinnant return false; 9824c0de496SHoward Hinnant } 9833e519524SHoward Hinnant __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; 9843e519524SHoward Hinnant __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word); 9853e519524SHoward Hinnant __dn -= __ddn; 9863e519524SHoward Hinnant if (__dn > 0) 9873e519524SHoward Hinnant { 9883e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __dn); 9893e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) 9903e519524SHoward Hinnant return false; 9913e519524SHoward Hinnant __first2.__ctz_ = static_cast<unsigned>(__dn); 9923e519524SHoward Hinnant } 9933e519524SHoward Hinnant ++__first1.__seg_; 9943e519524SHoward Hinnant // __first1.__ctz_ = 0; 9953e519524SHoward Hinnant } 9963e519524SHoward Hinnant // __first1.__ctz_ == 0; 9973e519524SHoward Hinnant // do middle words 9983e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __first2.__ctz_; 9993e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) << __first2.__ctz_; 10003e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) 10013e519524SHoward Hinnant { 10023e519524SHoward Hinnant __storage_type __b = *__first1.__seg_; 10033e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) 10043e519524SHoward Hinnant return false; 10053e519524SHoward Hinnant ++__first2.__seg_; 10063e519524SHoward Hinnant if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) 10073e519524SHoward Hinnant return false; 10083e519524SHoward Hinnant } 10093e519524SHoward Hinnant // do last word 10103e519524SHoward Hinnant if (__n > 0) 10113e519524SHoward Hinnant { 10123e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 10133e519524SHoward Hinnant __storage_type __b = *__first1.__seg_ & __m; 1014ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r)); 10153e519524SHoward Hinnant __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 10163e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) 10173e519524SHoward Hinnant return false; 10183e519524SHoward Hinnant __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; 10193e519524SHoward Hinnant __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word); 10203e519524SHoward Hinnant __n -= __dn; 10213e519524SHoward Hinnant if (__n > 0) 10223e519524SHoward Hinnant { 10233e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 10243e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b >> __dn)) 10253e519524SHoward Hinnant return false; 10263e519524SHoward Hinnant } 10273e519524SHoward Hinnant } 10283e519524SHoward Hinnant } 10293e519524SHoward Hinnant return true; 10303e519524SHoward Hinnant} 10313e519524SHoward Hinnant 10321237dccaSHoward Hinnanttemplate <class _Cp, bool _IC1, bool _IC2> 10333e519524SHoward Hinnantbool 10341237dccaSHoward Hinnant__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, 10351237dccaSHoward Hinnant __bit_iterator<_Cp, _IC2> __first2) 10363e519524SHoward Hinnant{ 10371237dccaSHoward Hinnant typedef __bit_iterator<_Cp, _IC1> _It; 10383e519524SHoward Hinnant typedef typename _It::difference_type difference_type; 10393e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 1040aec08784SEric Fiselier static const int __bits_per_word = _It::__bits_per_word; 10413e519524SHoward Hinnant difference_type __n = __last1 - __first1; 10423e519524SHoward Hinnant if (__n > 0) 10433e519524SHoward Hinnant { 10443e519524SHoward Hinnant // do first word 10453e519524SHoward Hinnant if (__first1.__ctz_ != 0) 10463e519524SHoward Hinnant { 10473e519524SHoward Hinnant unsigned __clz = __bits_per_word - __first1.__ctz_; 1048ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 10493e519524SHoward Hinnant __n -= __dn; 10503e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 10513e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) 10523e519524SHoward Hinnant return false; 10533e519524SHoward Hinnant ++__first2.__seg_; 10543e519524SHoward Hinnant ++__first1.__seg_; 10553e519524SHoward Hinnant // __first1.__ctz_ = 0; 10563e519524SHoward Hinnant // __first2.__ctz_ = 0; 10573e519524SHoward Hinnant } 10583e519524SHoward Hinnant // __first1.__ctz_ == 0; 10593e519524SHoward Hinnant // __first2.__ctz_ == 0; 10603e519524SHoward Hinnant // do middle words 10613e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) 10623e519524SHoward Hinnant if (*__first2.__seg_ != *__first1.__seg_) 10633e519524SHoward Hinnant return false; 10643e519524SHoward Hinnant // do last word 10653e519524SHoward Hinnant if (__n > 0) 10663e519524SHoward Hinnant { 10673e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 10683e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) 10693e519524SHoward Hinnant return false; 10703e519524SHoward Hinnant } 10713e519524SHoward Hinnant } 10723e519524SHoward Hinnant return true; 10733e519524SHoward Hinnant} 10743e519524SHoward Hinnant 1075c003db1fSHoward Hinnanttemplate <class _Cp, bool _IC1, bool _IC2> 107643d99238SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 10773e519524SHoward Hinnantbool 1078c003db1fSHoward Hinnantequal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) 10793e519524SHoward Hinnant{ 10803e519524SHoward Hinnant if (__first1.__ctz_ == __first2.__ctz_) 10813e519524SHoward Hinnant return __equal_aligned(__first1, __last1, __first2); 10823e519524SHoward Hinnant return __equal_unaligned(__first1, __last1, __first2); 10833e519524SHoward Hinnant} 10843e519524SHoward Hinnant 10850ae9efebSHoward Hinnanttemplate <class _Cp, bool _IsConst, 10860ae9efebSHoward Hinnant typename _Cp::__storage_type> 10873e519524SHoward Hinnantclass __bit_iterator 10883e519524SHoward Hinnant{ 10893e519524SHoward Hinnantpublic: 1090c003db1fSHoward Hinnant typedef typename _Cp::difference_type difference_type; 10913e519524SHoward Hinnant typedef bool value_type; 10923e519524SHoward Hinnant typedef __bit_iterator pointer; 1093c003db1fSHoward Hinnant typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference; 10943e519524SHoward Hinnant typedef random_access_iterator_tag iterator_category; 10953e519524SHoward Hinnant 10963e519524SHoward Hinnantprivate: 1097c003db1fSHoward Hinnant typedef typename _Cp::__storage_type __storage_type; 1098c003db1fSHoward Hinnant typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer, 1099c003db1fSHoward Hinnant typename _Cp::__storage_pointer>::type __storage_pointer; 1100c003db1fSHoward Hinnant static const unsigned __bits_per_word = _Cp::__bits_per_word; 11013e519524SHoward Hinnant 11023e519524SHoward Hinnant __storage_pointer __seg_; 11033e519524SHoward Hinnant unsigned __ctz_; 11043e519524SHoward Hinnant 11053e519524SHoward Hinnantpublic: 110636b2a3b0SMarshall Clow _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT 110736b2a3b0SMarshall Clow#if _LIBCPP_STD_VER > 11 110836b2a3b0SMarshall Clow : __seg_(nullptr), __ctz_(0) 110936b2a3b0SMarshall Clow#endif 111036b2a3b0SMarshall Clow {} 11113e519524SHoward Hinnant 1112d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1113c003db1fSHoward Hinnant __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT 11143e519524SHoward Hinnant : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} 11153e519524SHoward Hinnant 1116d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT 1117d368a84cSHoward Hinnant {return reference(__seg_, __storage_type(1) << __ctz_);} 11183e519524SHoward Hinnant 11193e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++() 11203e519524SHoward Hinnant { 11213e519524SHoward Hinnant if (__ctz_ != __bits_per_word-1) 11223e519524SHoward Hinnant ++__ctz_; 11233e519524SHoward Hinnant else 11243e519524SHoward Hinnant { 11253e519524SHoward Hinnant __ctz_ = 0; 11263e519524SHoward Hinnant ++__seg_; 11273e519524SHoward Hinnant } 11283e519524SHoward Hinnant return *this; 11293e519524SHoward Hinnant } 11303e519524SHoward Hinnant 11313e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int) 11323e519524SHoward Hinnant { 11333e519524SHoward Hinnant __bit_iterator __tmp = *this; 11343e519524SHoward Hinnant ++(*this); 11353e519524SHoward Hinnant return __tmp; 11363e519524SHoward Hinnant } 11373e519524SHoward Hinnant 11383e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--() 11393e519524SHoward Hinnant { 11403e519524SHoward Hinnant if (__ctz_ != 0) 11413e519524SHoward Hinnant --__ctz_; 11423e519524SHoward Hinnant else 11433e519524SHoward Hinnant { 11443e519524SHoward Hinnant __ctz_ = __bits_per_word - 1; 11453e519524SHoward Hinnant --__seg_; 11463e519524SHoward Hinnant } 11473e519524SHoward Hinnant return *this; 11483e519524SHoward Hinnant } 11493e519524SHoward Hinnant 11503e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int) 11513e519524SHoward Hinnant { 11523e519524SHoward Hinnant __bit_iterator __tmp = *this; 11533e519524SHoward Hinnant --(*this); 11543e519524SHoward Hinnant return __tmp; 11553e519524SHoward Hinnant } 11563e519524SHoward Hinnant 11573e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n) 11583e519524SHoward Hinnant { 11593e519524SHoward Hinnant if (__n >= 0) 11603e519524SHoward Hinnant __seg_ += (__n + __ctz_) / __bits_per_word; 11613e519524SHoward Hinnant else 11623e519524SHoward Hinnant __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) 11633e519524SHoward Hinnant / static_cast<difference_type>(__bits_per_word); 11643e519524SHoward Hinnant __n &= (__bits_per_word - 1); 11653e519524SHoward Hinnant __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word); 11663e519524SHoward Hinnant return *this; 11673e519524SHoward Hinnant } 11683e519524SHoward Hinnant 11693e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n) 11703e519524SHoward Hinnant { 11713e519524SHoward Hinnant return *this += -__n; 11723e519524SHoward Hinnant } 11733e519524SHoward Hinnant 11743e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const 11753e519524SHoward Hinnant { 11763e519524SHoward Hinnant __bit_iterator __t(*this); 11773e519524SHoward Hinnant __t += __n; 11783e519524SHoward Hinnant return __t; 11793e519524SHoward Hinnant } 11803e519524SHoward Hinnant 11813e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const 11823e519524SHoward Hinnant { 11833e519524SHoward Hinnant __bit_iterator __t(*this); 11843e519524SHoward Hinnant __t -= __n; 11853e519524SHoward Hinnant return __t; 11863e519524SHoward Hinnant } 11873e519524SHoward Hinnant 11883e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 11893e519524SHoward Hinnant friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;} 11903e519524SHoward Hinnant 11913e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 11923e519524SHoward Hinnant friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) 11933e519524SHoward Hinnant {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;} 11943e519524SHoward Hinnant 11953e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);} 11963e519524SHoward Hinnant 11973e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) 11983e519524SHoward Hinnant {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;} 11993e519524SHoward Hinnant 12003e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) 12013e519524SHoward Hinnant {return !(__x == __y);} 12023e519524SHoward Hinnant 12033e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) 12043e519524SHoward Hinnant {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);} 12053e519524SHoward Hinnant 12063e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) 12073e519524SHoward Hinnant {return __y < __x;} 12083e519524SHoward Hinnant 12093e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) 12103e519524SHoward Hinnant {return !(__y < __x);} 12113e519524SHoward Hinnant 12123e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) 12133e519524SHoward Hinnant {return !(__x < __y);} 12143e519524SHoward Hinnant 12153e519524SHoward Hinnantprivate: 12163e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1217d368a84cSHoward Hinnant __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT 1218d368a84cSHoward Hinnant : __seg_(__s), __ctz_(__ctz) {} 12193e519524SHoward Hinnant 1220c003db1fSHoward Hinnant friend typename _Cp::__self; 1221541f9e28SEric Fiselier 1222c003db1fSHoward Hinnant friend class __bit_reference<_Cp>; 1223c003db1fSHoward Hinnant friend class __bit_const_reference<_Cp>; 1224c003db1fSHoward Hinnant friend class __bit_iterator<_Cp, true>; 1225c003db1fSHoward Hinnant template <class _Dp> friend struct __bit_array; 1226c003db1fSHoward Hinnant template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); 1227c003db1fSHoward Hinnant template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); 1228c003db1fSHoward Hinnant template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first, 1229c003db1fSHoward Hinnant __bit_iterator<_Dp, _IC> __last, 1230c003db1fSHoward Hinnant __bit_iterator<_Dp, false> __result); 1231c003db1fSHoward Hinnant template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first, 1232c003db1fSHoward Hinnant __bit_iterator<_Dp, _IC> __last, 1233c003db1fSHoward Hinnant __bit_iterator<_Dp, false> __result); 1234c003db1fSHoward Hinnant template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first, 1235c003db1fSHoward Hinnant __bit_iterator<_Dp, _IC> __last, 1236c003db1fSHoward Hinnant __bit_iterator<_Dp, false> __result); 1237c003db1fSHoward Hinnant template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first, 1238c003db1fSHoward Hinnant __bit_iterator<_Dp, _IC> __last, 1239c003db1fSHoward Hinnant __bit_iterator<_Dp, false> __result); 1240c003db1fSHoward Hinnant template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first, 1241c003db1fSHoward Hinnant __bit_iterator<_Dp, _IC> __last, 1242c003db1fSHoward Hinnant __bit_iterator<_Dp, false> __result); 1243c003db1fSHoward Hinnant template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, 1244c003db1fSHoward Hinnant __bit_iterator<_Dp, _IC> __last, 1245c003db1fSHoward Hinnant __bit_iterator<_Dp, false> __result); 1246dbe81119SHoward Hinnant template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, 1247dbe81119SHoward Hinnant __bit_iterator<__C1, false>, 1248dbe81119SHoward Hinnant __bit_iterator<__C2, false>); 1249dbe81119SHoward Hinnant template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>, 1250dbe81119SHoward Hinnant __bit_iterator<__C1, false>, 1251dbe81119SHoward Hinnant __bit_iterator<__C2, false>); 1252dbe81119SHoward Hinnant template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, 1253dbe81119SHoward Hinnant __bit_iterator<__C1, false>, 1254dbe81119SHoward Hinnant __bit_iterator<__C2, false>); 1255c003db1fSHoward Hinnant template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, 1256c003db1fSHoward Hinnant __bit_iterator<_Dp, false>, 1257c003db1fSHoward Hinnant __bit_iterator<_Dp, false>); 12581237dccaSHoward Hinnant template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, 12591237dccaSHoward Hinnant __bit_iterator<_Dp, _IC1>, 12601237dccaSHoward Hinnant __bit_iterator<_Dp, _IC2>); 12611237dccaSHoward Hinnant template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, 12621237dccaSHoward Hinnant __bit_iterator<_Dp, _IC1>, 12631237dccaSHoward Hinnant __bit_iterator<_Dp, _IC2>); 1264c003db1fSHoward Hinnant template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>, 1265c003db1fSHoward Hinnant __bit_iterator<_Dp, _IC1>, 1266c003db1fSHoward Hinnant __bit_iterator<_Dp, _IC2>); 1267423a8d77SHoward Hinnant template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, 1268c003db1fSHoward Hinnant typename _Dp::size_type); 1269423a8d77SHoward Hinnant template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, 1270c003db1fSHoward Hinnant typename _Dp::size_type); 1271423a8d77SHoward Hinnant template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type 1272423a8d77SHoward Hinnant __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); 1273423a8d77SHoward Hinnant template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type 1274423a8d77SHoward Hinnant __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); 12753e519524SHoward Hinnant}; 12763e519524SHoward Hinnant 12773e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD 12783e519524SHoward Hinnant 1279a016efb1SEric Fiselier_LIBCPP_POP_MACROS 1280a016efb1SEric Fiselier 12813e519524SHoward Hinnant#endif // _LIBCPP___BIT_REFERENCE 1282