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> 153e519524SHoward Hinnant#include <algorithm> 163e519524SHoward Hinnant 17073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 183e519524SHoward Hinnant#pragma GCC system_header 19073458b1SHoward Hinnant#endif 203e519524SHoward Hinnant 213e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 223e519524SHoward Hinnant 233e519524SHoward Hinnanttemplate <class _C, bool _IsConst> class __bit_iterator; 243e519524SHoward Hinnanttemplate <class _C> class __bit_const_reference; 253e519524SHoward Hinnant 26a7744562SHoward Hinnanttemplate <class _Tp> 27a7744562SHoward Hinnantstruct __has_storage_type 28a7744562SHoward Hinnant{ 29a7744562SHoward Hinnant static const bool value = false; 30a7744562SHoward Hinnant}; 31a7744562SHoward Hinnant 32a7744562SHoward Hinnanttemplate <class _C, bool = __has_storage_type<_C>::value> 333e519524SHoward Hinnantclass __bit_reference 343e519524SHoward Hinnant{ 353e519524SHoward Hinnant typedef typename _C::__storage_type __storage_type; 363e519524SHoward Hinnant typedef typename _C::__storage_pointer __storage_pointer; 373e519524SHoward Hinnant 383e519524SHoward Hinnant __storage_pointer __seg_; 393e519524SHoward Hinnant __storage_type __mask_; 403e519524SHoward Hinnant 413e519524SHoward Hinnant#if defined(__clang__) 423e519524SHoward Hinnant friend typename _C::__self; 433e519524SHoward Hinnant#else 443e519524SHoward Hinnant friend class _C::__self; 453e519524SHoward Hinnant#endif 463e519524SHoward Hinnant friend class __bit_const_reference<_C>; 473e519524SHoward Hinnant friend class __bit_iterator<_C, false>; 483e519524SHoward Hinnantpublic: 49d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT 50d368a84cSHoward Hinnant {return static_cast<bool>(*__seg_ & __mask_);} 51d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT 52d368a84cSHoward Hinnant {return !static_cast<bool>(*this);} 533e519524SHoward Hinnant 543e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 55d368a84cSHoward Hinnant __bit_reference& operator=(bool __x) _NOEXCEPT 563e519524SHoward Hinnant { 573e519524SHoward Hinnant if (__x) 583e519524SHoward Hinnant *__seg_ |= __mask_; 593e519524SHoward Hinnant else 603e519524SHoward Hinnant *__seg_ &= ~__mask_; 613e519524SHoward Hinnant return *this; 623e519524SHoward Hinnant } 633e519524SHoward Hinnant 643e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 65d368a84cSHoward Hinnant __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT 66d368a84cSHoward Hinnant {return operator=(static_cast<bool>(__x));} 673e519524SHoward Hinnant 68d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;} 69d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator<_C, false> operator&() const _NOEXCEPT 703e519524SHoward Hinnant {return __bit_iterator<_C, false>(__seg_, static_cast<unsigned>(__ctz(__mask_)));} 713e519524SHoward Hinnantprivate: 723e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 73d368a84cSHoward Hinnant __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 74d368a84cSHoward Hinnant : __seg_(__s), __mask_(__m) {} 753e519524SHoward Hinnant}; 763e519524SHoward Hinnant 77a7744562SHoward Hinnanttemplate <class _C> 78a7744562SHoward Hinnantclass __bit_reference<_C, false> 79a7744562SHoward Hinnant{ 80a7744562SHoward Hinnant}; 81a7744562SHoward Hinnant 823e519524SHoward Hinnanttemplate <class _C, class _D> 833e519524SHoward Hinnant_LIBCPP_INLINE_VISIBILITY inline 843e519524SHoward Hinnantvoid 85d368a84cSHoward Hinnantswap(__bit_reference<_C> __x, __bit_reference<_D> __y) _NOEXCEPT 863e519524SHoward Hinnant{ 873e519524SHoward Hinnant bool __t = __x; 883e519524SHoward Hinnant __x = __y; 893e519524SHoward Hinnant __y = __t; 903e519524SHoward Hinnant} 913e519524SHoward Hinnant 923e519524SHoward Hinnanttemplate <class _C> 933e519524SHoward Hinnant_LIBCPP_INLINE_VISIBILITY inline 943e519524SHoward Hinnantvoid 95d368a84cSHoward Hinnantswap(__bit_reference<_C> __x, bool& __y) _NOEXCEPT 963e519524SHoward Hinnant{ 973e519524SHoward Hinnant bool __t = __x; 983e519524SHoward Hinnant __x = __y; 993e519524SHoward Hinnant __y = __t; 1003e519524SHoward Hinnant} 1013e519524SHoward Hinnant 1023e519524SHoward Hinnanttemplate <class _C> 1033e519524SHoward Hinnant_LIBCPP_INLINE_VISIBILITY inline 1043e519524SHoward Hinnantvoid 105d368a84cSHoward Hinnantswap(bool& __x, __bit_reference<_C> __y) _NOEXCEPT 1063e519524SHoward Hinnant{ 1073e519524SHoward Hinnant bool __t = __x; 1083e519524SHoward Hinnant __x = __y; 1093e519524SHoward Hinnant __y = __t; 1103e519524SHoward Hinnant} 1113e519524SHoward Hinnant 1123e519524SHoward Hinnanttemplate <class _C> 1133e519524SHoward Hinnantclass __bit_const_reference 1143e519524SHoward Hinnant{ 1153e519524SHoward Hinnant typedef typename _C::__storage_type __storage_type; 1163e519524SHoward Hinnant typedef typename _C::__const_storage_pointer __storage_pointer; 1173e519524SHoward Hinnant 1183e519524SHoward Hinnant __storage_pointer __seg_; 1193e519524SHoward Hinnant __storage_type __mask_; 1203e519524SHoward Hinnant 1213e519524SHoward Hinnant#if defined(__clang__) 1223e519524SHoward Hinnant friend typename _C::__self; 1233e519524SHoward Hinnant#else 1243e519524SHoward Hinnant friend class _C::__self; 1253e519524SHoward Hinnant#endif 1263e519524SHoward Hinnant friend class __bit_iterator<_C, true>; 1273e519524SHoward Hinnantpublic: 1283e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 129d368a84cSHoward Hinnant __bit_const_reference(const __bit_reference<_C>& __x) _NOEXCEPT 1303e519524SHoward Hinnant : __seg_(__x.__seg_), __mask_(__x.__mask_) {} 1313e519524SHoward Hinnant 132d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT 133d368a84cSHoward Hinnant {return static_cast<bool>(*__seg_ & __mask_);} 1343e519524SHoward Hinnant 135d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator<_C, true> operator&() const _NOEXCEPT 1363e519524SHoward Hinnant {return __bit_iterator<_C, true>(__seg_, static_cast<unsigned>(__ctz(__mask_)));} 1373e519524SHoward Hinnantprivate: 1383e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 139d368a84cSHoward Hinnant __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 140d368a84cSHoward Hinnant : __seg_(__s), __mask_(__m) {} 1413e519524SHoward Hinnant 1423e519524SHoward Hinnant __bit_const_reference& operator=(const __bit_const_reference& __x); 1433e519524SHoward Hinnant}; 1443e519524SHoward Hinnant 1453e519524SHoward Hinnant// find 1463e519524SHoward Hinnant 1473e519524SHoward Hinnanttemplate <class _C> 1483e519524SHoward Hinnant__bit_iterator<_C, false> 1493e519524SHoward Hinnant__find_bool_true(__bit_iterator<_C, false> __first, typename _C::size_type __n) 1503e519524SHoward Hinnant{ 1513e519524SHoward Hinnant typedef __bit_iterator<_C, false> _It; 1523e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 1533e519524SHoward Hinnant static const unsigned __bits_per_word = _It::__bits_per_word; 1543e519524SHoward Hinnant // do first partial word 1553e519524SHoward Hinnant if (__first.__ctz_ != 0) 1563e519524SHoward Hinnant { 1573e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 158ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 1593e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 1603e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 1613e519524SHoward Hinnant if (__b) 162ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 1633e519524SHoward Hinnant __n -= __dn; 1643e519524SHoward Hinnant ++__first.__seg_; 1653e519524SHoward Hinnant } 1663e519524SHoward Hinnant // do middle whole words 1673e519524SHoward Hinnant for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 1683e519524SHoward Hinnant if (*__first.__seg_) 169ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(*__first.__seg_))); 1703e519524SHoward Hinnant // do last partial word 1713e519524SHoward Hinnant if (__n > 0) 1723e519524SHoward Hinnant { 1733e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 1743e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 1753e519524SHoward Hinnant if (__b) 176ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 1773e519524SHoward Hinnant } 1783e519524SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(__n)); 1793e519524SHoward Hinnant} 1803e519524SHoward Hinnant 1813e519524SHoward Hinnanttemplate <class _C> 1823e519524SHoward Hinnant__bit_iterator<_C, false> 1833e519524SHoward Hinnant__find_bool_false(__bit_iterator<_C, false> __first, typename _C::size_type __n) 1843e519524SHoward Hinnant{ 1853e519524SHoward Hinnant typedef __bit_iterator<_C, false> _It; 1863e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 1873e519524SHoward Hinnant static const unsigned __bits_per_word = _It::__bits_per_word; 1883e519524SHoward Hinnant // do first partial word 1893e519524SHoward Hinnant if (__first.__ctz_ != 0) 1903e519524SHoward Hinnant { 1913e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 192ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 1933e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 1943e519524SHoward Hinnant __storage_type __b = ~(*__first.__seg_ & __m); 1953e519524SHoward Hinnant if (__b) 196ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 1973e519524SHoward Hinnant __n -= __dn; 1983e519524SHoward Hinnant ++__first.__seg_; 1993e519524SHoward Hinnant } 2003e519524SHoward Hinnant // do middle whole words 2013e519524SHoward Hinnant for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 2023e519524SHoward Hinnant { 2033e519524SHoward Hinnant __storage_type __b = ~*__first.__seg_; 2043e519524SHoward Hinnant if (__b) 205ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 2063e519524SHoward Hinnant } 2073e519524SHoward Hinnant // do last partial word 2083e519524SHoward Hinnant if (__n > 0) 2093e519524SHoward Hinnant { 2103e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 2113e519524SHoward Hinnant __storage_type __b = ~(*__first.__seg_ & __m); 2123e519524SHoward Hinnant if (__b) 213ce48a113SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b))); 2143e519524SHoward Hinnant } 2153e519524SHoward Hinnant return _It(__first.__seg_, static_cast<unsigned>(__n)); 2163e519524SHoward Hinnant} 2173e519524SHoward Hinnant 2183e519524SHoward Hinnanttemplate <class _C, class _Tp> 2193e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 2203e519524SHoward Hinnant__bit_iterator<_C, false> 221*e4383379SHoward Hinnantfind(__bit_iterator<_C, false> __first, __bit_iterator<_C, false> __last, const _Tp& __value_) 2223e519524SHoward Hinnant{ 223*e4383379SHoward Hinnant if (static_cast<bool>(__value_)) 2243e519524SHoward Hinnant return __find_bool_true(__first, static_cast<typename _C::size_type>(__last - __first)); 2253e519524SHoward Hinnant return __find_bool_false(__first, static_cast<typename _C::size_type>(__last - __first)); 2263e519524SHoward Hinnant} 2273e519524SHoward Hinnant 2283e519524SHoward Hinnant// count 2293e519524SHoward Hinnant 2303e519524SHoward Hinnanttemplate <class _C> 2313e519524SHoward Hinnanttypename __bit_iterator<_C, false>::difference_type 2323e519524SHoward Hinnant__count_bool_true(__bit_iterator<_C, false> __first, typename _C::size_type __n) 2333e519524SHoward Hinnant{ 2343e519524SHoward Hinnant typedef __bit_iterator<_C, false> _It; 2353e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 2363e519524SHoward Hinnant typedef typename _It::difference_type difference_type; 2373e519524SHoward Hinnant static const unsigned __bits_per_word = _It::__bits_per_word; 2383e519524SHoward Hinnant difference_type __r = 0; 2393e519524SHoward Hinnant // do first partial word 2403e519524SHoward Hinnant if (__first.__ctz_ != 0) 2413e519524SHoward Hinnant { 2423e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 243ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 2443e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 245ce48a113SHoward Hinnant __r = _VSTD::__pop_count(*__first.__seg_ & __m); 2463e519524SHoward Hinnant __n -= __dn; 2473e519524SHoward Hinnant ++__first.__seg_; 2483e519524SHoward Hinnant } 2493e519524SHoward Hinnant // do middle whole words 2503e519524SHoward Hinnant for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 251ce48a113SHoward Hinnant __r += _VSTD::__pop_count(*__first.__seg_); 2523e519524SHoward Hinnant // do last partial word 2533e519524SHoward Hinnant if (__n > 0) 2543e519524SHoward Hinnant { 2553e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 256ce48a113SHoward Hinnant __r += _VSTD::__pop_count(*__first.__seg_ & __m); 2573e519524SHoward Hinnant } 2583e519524SHoward Hinnant return __r; 2593e519524SHoward Hinnant} 2603e519524SHoward Hinnant 2613e519524SHoward Hinnanttemplate <class _C> 2623e519524SHoward Hinnanttypename __bit_iterator<_C, false>::difference_type 2633e519524SHoward Hinnant__count_bool_false(__bit_iterator<_C, false> __first, typename _C::size_type __n) 2643e519524SHoward Hinnant{ 2653e519524SHoward Hinnant typedef __bit_iterator<_C, false> _It; 2663e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 2673e519524SHoward Hinnant typedef typename _It::difference_type difference_type; 2683e519524SHoward Hinnant static const unsigned __bits_per_word = _It::__bits_per_word; 2693e519524SHoward Hinnant difference_type __r = 0; 2703e519524SHoward Hinnant // do first partial word 2713e519524SHoward Hinnant if (__first.__ctz_ != 0) 2723e519524SHoward Hinnant { 2733e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 274ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 2753e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 276ce48a113SHoward Hinnant __r = _VSTD::__pop_count(~(*__first.__seg_ & __m)); 2773e519524SHoward Hinnant __n -= __dn; 2783e519524SHoward Hinnant ++__first.__seg_; 2793e519524SHoward Hinnant } 2803e519524SHoward Hinnant // do middle whole words 2813e519524SHoward Hinnant for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 282ce48a113SHoward Hinnant __r += _VSTD::__pop_count(~*__first.__seg_); 2833e519524SHoward Hinnant // do last partial word 2843e519524SHoward Hinnant if (__n > 0) 2853e519524SHoward Hinnant { 2863e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 287ce48a113SHoward Hinnant __r += _VSTD::__pop_count(~(*__first.__seg_ & __m)); 2883e519524SHoward Hinnant } 2893e519524SHoward Hinnant return __r; 2903e519524SHoward Hinnant} 2913e519524SHoward Hinnant 2923e519524SHoward Hinnanttemplate <class _C, class _Tp> 2933e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 2943e519524SHoward Hinnanttypename __bit_iterator<_C, false>::difference_type 295*e4383379SHoward Hinnantcount(__bit_iterator<_C, false> __first, __bit_iterator<_C, false> __last, const _Tp& __value_) 2963e519524SHoward Hinnant{ 297*e4383379SHoward Hinnant if (static_cast<bool>(__value_)) 2983e519524SHoward Hinnant return __count_bool_true(__first, static_cast<typename _C::size_type>(__last - __first)); 2993e519524SHoward Hinnant return __count_bool_false(__first, static_cast<typename _C::size_type>(__last - __first)); 3003e519524SHoward Hinnant} 3013e519524SHoward Hinnant 3023e519524SHoward Hinnant// fill_n 3033e519524SHoward Hinnant 3043e519524SHoward Hinnanttemplate <class _C> 3053e519524SHoward Hinnantvoid 3063e519524SHoward Hinnant__fill_n_false(__bit_iterator<_C, false> __first, typename _C::size_type __n) 3073e519524SHoward Hinnant{ 3083e519524SHoward Hinnant typedef __bit_iterator<_C, false> _It; 3093e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 3103e519524SHoward Hinnant static const unsigned __bits_per_word = _It::__bits_per_word; 3113e519524SHoward Hinnant // do first partial word 3123e519524SHoward Hinnant if (__first.__ctz_ != 0) 3133e519524SHoward Hinnant { 3143e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 315ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 3163e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 3173e519524SHoward Hinnant *__first.__seg_ &= ~__m; 3183e519524SHoward Hinnant __n -= __dn; 3193e519524SHoward Hinnant ++__first.__seg_; 3203e519524SHoward Hinnant } 3213e519524SHoward Hinnant // do middle whole words 3223e519524SHoward Hinnant __storage_type __nw = __n / __bits_per_word; 323ce48a113SHoward Hinnant _VSTD::memset(__first.__seg_, 0, __nw * sizeof(__storage_type)); 3243e519524SHoward Hinnant __n -= __nw * __bits_per_word; 3253e519524SHoward Hinnant // do last partial word 3263e519524SHoward Hinnant if (__n > 0) 3273e519524SHoward Hinnant { 3283e519524SHoward Hinnant __first.__seg_ += __nw; 3293e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 3303e519524SHoward Hinnant *__first.__seg_ &= ~__m; 3313e519524SHoward Hinnant } 3323e519524SHoward Hinnant} 3333e519524SHoward Hinnant 3343e519524SHoward Hinnanttemplate <class _C> 3353e519524SHoward Hinnantvoid 3363e519524SHoward Hinnant__fill_n_true(__bit_iterator<_C, false> __first, typename _C::size_type __n) 3373e519524SHoward Hinnant{ 3383e519524SHoward Hinnant typedef __bit_iterator<_C, false> _It; 3393e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 3403e519524SHoward Hinnant static const unsigned __bits_per_word = _It::__bits_per_word; 3413e519524SHoward Hinnant // do first partial word 3423e519524SHoward Hinnant if (__first.__ctz_ != 0) 3433e519524SHoward Hinnant { 3443e519524SHoward Hinnant __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 345ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__clz_f, __n); 3463e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 3473e519524SHoward Hinnant *__first.__seg_ |= __m; 3483e519524SHoward Hinnant __n -= __dn; 3493e519524SHoward Hinnant ++__first.__seg_; 3503e519524SHoward Hinnant } 3513e519524SHoward Hinnant // do middle whole words 3523e519524SHoward Hinnant __storage_type __nw = __n / __bits_per_word; 353ce48a113SHoward Hinnant _VSTD::memset(__first.__seg_, -1, __nw * sizeof(__storage_type)); 3543e519524SHoward Hinnant __n -= __nw * __bits_per_word; 3553e519524SHoward Hinnant // do last partial word 3563e519524SHoward Hinnant if (__n > 0) 3573e519524SHoward Hinnant { 3583e519524SHoward Hinnant __first.__seg_ += __nw; 3593e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 3603e519524SHoward Hinnant *__first.__seg_ |= __m; 3613e519524SHoward Hinnant } 3623e519524SHoward Hinnant} 3633e519524SHoward Hinnant 3643e519524SHoward Hinnanttemplate <class _C> 3653e519524SHoward Hinnant_LIBCPP_INLINE_VISIBILITY inline 3663e519524SHoward Hinnantvoid 367*e4383379SHoward Hinnantfill_n(__bit_iterator<_C, false> __first, typename _C::size_type __n, bool __value_) 3683e519524SHoward Hinnant{ 3693e519524SHoward Hinnant if (__n > 0) 3703e519524SHoward Hinnant { 371*e4383379SHoward Hinnant if (__value_) 3723e519524SHoward Hinnant __fill_n_true(__first, __n); 3733e519524SHoward Hinnant else 3743e519524SHoward Hinnant __fill_n_false(__first, __n); 3753e519524SHoward Hinnant } 3763e519524SHoward Hinnant} 3773e519524SHoward Hinnant 3783e519524SHoward Hinnant// fill 3793e519524SHoward Hinnant 3803e519524SHoward Hinnanttemplate <class _C> 3813e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 3823e519524SHoward Hinnantvoid 383*e4383379SHoward Hinnantfill(__bit_iterator<_C, false> __first, __bit_iterator<_C, false> __last, bool __value_) 3843e519524SHoward Hinnant{ 385*e4383379SHoward Hinnant _VSTD::fill_n(__first, static_cast<typename _C::size_type>(__last - __first), __value_); 3863e519524SHoward Hinnant} 3873e519524SHoward Hinnant 3883e519524SHoward Hinnant// copy 3893e519524SHoward Hinnant 3903e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 3913e519524SHoward Hinnant__bit_iterator<_C, false> 3923e519524SHoward Hinnant__copy_aligned(__bit_iterator<_C, _IsConst> __first, __bit_iterator<_C, _IsConst> __last, 3933e519524SHoward Hinnant __bit_iterator<_C, false> __result) 3943e519524SHoward Hinnant{ 3953e519524SHoward Hinnant typedef __bit_iterator<_C, _IsConst> _In; 3963e519524SHoward Hinnant typedef typename _In::difference_type difference_type; 3973e519524SHoward Hinnant typedef typename _In::__storage_type __storage_type; 3983e519524SHoward Hinnant static const unsigned __bits_per_word = _In::__bits_per_word; 3993e519524SHoward Hinnant difference_type __n = __last - __first; 4003e519524SHoward Hinnant if (__n > 0) 4013e519524SHoward Hinnant { 4023e519524SHoward Hinnant // do first word 4033e519524SHoward Hinnant if (__first.__ctz_ != 0) 4043e519524SHoward Hinnant { 4053e519524SHoward Hinnant unsigned __clz = __bits_per_word - __first.__ctz_; 406ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 4073e519524SHoward Hinnant __n -= __dn; 4083e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 4093e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 4103e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4113e519524SHoward Hinnant *__result.__seg_ |= __b; 4123e519524SHoward Hinnant __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 4133e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 4143e519524SHoward Hinnant ++__first.__seg_; 4153e519524SHoward Hinnant // __first.__ctz_ = 0; 4163e519524SHoward Hinnant } 4173e519524SHoward Hinnant // __first.__ctz_ == 0; 4183e519524SHoward Hinnant // do middle words 4193e519524SHoward Hinnant __storage_type __nw = __n / __bits_per_word; 420ce48a113SHoward Hinnant _VSTD::memmove(__result.__seg_, __first.__seg_, __nw * sizeof(__storage_type)); 4213e519524SHoward Hinnant __n -= __nw * __bits_per_word; 4223e519524SHoward Hinnant __result.__seg_ += __nw; 4233e519524SHoward Hinnant // do last word 4243e519524SHoward Hinnant if (__n > 0) 4253e519524SHoward Hinnant { 4263e519524SHoward Hinnant __first.__seg_ += __nw; 4273e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 4283e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 4293e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4303e519524SHoward Hinnant *__result.__seg_ |= __b; 4313e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__n); 4323e519524SHoward Hinnant } 4333e519524SHoward Hinnant } 4343e519524SHoward Hinnant return __result; 4353e519524SHoward Hinnant} 4363e519524SHoward Hinnant 4373e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 4383e519524SHoward Hinnant__bit_iterator<_C, false> 4393e519524SHoward Hinnant__copy_unaligned(__bit_iterator<_C, _IsConst> __first, __bit_iterator<_C, _IsConst> __last, 4403e519524SHoward Hinnant __bit_iterator<_C, false> __result) 4413e519524SHoward Hinnant{ 4423e519524SHoward Hinnant typedef __bit_iterator<_C, _IsConst> _In; 4433e519524SHoward Hinnant typedef typename _In::difference_type difference_type; 4443e519524SHoward Hinnant typedef typename _In::__storage_type __storage_type; 4453e519524SHoward Hinnant static const unsigned __bits_per_word = _In::__bits_per_word; 4463e519524SHoward Hinnant difference_type __n = __last - __first; 4473e519524SHoward Hinnant if (__n > 0) 4483e519524SHoward Hinnant { 4493e519524SHoward Hinnant // do first word 4503e519524SHoward Hinnant if (__first.__ctz_ != 0) 4513e519524SHoward Hinnant { 4523e519524SHoward Hinnant unsigned __clz_f = __bits_per_word - __first.__ctz_; 453ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 4543e519524SHoward Hinnant __n -= __dn; 4553e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 4563e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 4573e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 458ce48a113SHoward Hinnant __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 4593e519524SHoward Hinnant __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 4603e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4613e519524SHoward Hinnant if (__result.__ctz_ > __first.__ctz_) 4623e519524SHoward Hinnant *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); 4633e519524SHoward Hinnant else 4643e519524SHoward Hinnant *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); 4653e519524SHoward Hinnant __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; 4663e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); 4673e519524SHoward Hinnant __dn -= __ddn; 4683e519524SHoward Hinnant if (__dn > 0) 4693e519524SHoward Hinnant { 4703e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __dn); 4713e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4723e519524SHoward Hinnant *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); 4733e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__dn); 4743e519524SHoward Hinnant } 4753e519524SHoward Hinnant ++__first.__seg_; 4763e519524SHoward Hinnant // __first.__ctz_ = 0; 4773e519524SHoward Hinnant } 4783e519524SHoward Hinnant // __first.__ctz_ == 0; 4793e519524SHoward Hinnant // do middle words 4803e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 4813e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) << __result.__ctz_; 4823e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) 4833e519524SHoward Hinnant { 4843e519524SHoward Hinnant __storage_type __b = *__first.__seg_; 4853e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4863e519524SHoward Hinnant *__result.__seg_ |= __b << __result.__ctz_; 4873e519524SHoward Hinnant ++__result.__seg_; 4883e519524SHoward Hinnant *__result.__seg_ &= __m; 4893e519524SHoward Hinnant *__result.__seg_ |= __b >> __clz_r; 4903e519524SHoward Hinnant } 4913e519524SHoward Hinnant // do last word 4923e519524SHoward Hinnant if (__n > 0) 4933e519524SHoward Hinnant { 4943e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 4953e519524SHoward Hinnant __storage_type __b = *__first.__seg_ & __m; 496ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r)); 4973e519524SHoward Hinnant __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 4983e519524SHoward Hinnant *__result.__seg_ &= ~__m; 4993e519524SHoward Hinnant *__result.__seg_ |= __b << __result.__ctz_; 5003e519524SHoward Hinnant __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 5013e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 5023e519524SHoward Hinnant __n -= __dn; 5033e519524SHoward Hinnant if (__n > 0) 5043e519524SHoward Hinnant { 5053e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 5063e519524SHoward Hinnant *__result.__seg_ &= ~__m; 5073e519524SHoward Hinnant *__result.__seg_ |= __b >> __dn; 5083e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__n); 5093e519524SHoward Hinnant } 5103e519524SHoward Hinnant } 5113e519524SHoward Hinnant } 5123e519524SHoward Hinnant return __result; 5133e519524SHoward Hinnant} 5143e519524SHoward Hinnant 5153e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 5163e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 5173e519524SHoward Hinnant__bit_iterator<_C, false> 5183e519524SHoward Hinnantcopy(__bit_iterator<_C, _IsConst> __first, __bit_iterator<_C, _IsConst> __last, __bit_iterator<_C, false> __result) 5193e519524SHoward Hinnant{ 5203e519524SHoward Hinnant if (__first.__ctz_ == __result.__ctz_) 5213e519524SHoward Hinnant return __copy_aligned(__first, __last, __result); 5223e519524SHoward Hinnant return __copy_unaligned(__first, __last, __result); 5233e519524SHoward Hinnant} 5243e519524SHoward Hinnant 5253e519524SHoward Hinnant// copy_backward 5263e519524SHoward Hinnant 5273e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 5283e519524SHoward Hinnant__bit_iterator<_C, false> 5293e519524SHoward Hinnant__copy_backward_aligned(__bit_iterator<_C, _IsConst> __first, __bit_iterator<_C, _IsConst> __last, 5303e519524SHoward Hinnant __bit_iterator<_C, false> __result) 5313e519524SHoward Hinnant{ 5323e519524SHoward Hinnant typedef __bit_iterator<_C, _IsConst> _In; 5333e519524SHoward Hinnant typedef typename _In::difference_type difference_type; 5343e519524SHoward Hinnant typedef typename _In::__storage_type __storage_type; 5353e519524SHoward Hinnant static const unsigned __bits_per_word = _In::__bits_per_word; 5363e519524SHoward Hinnant difference_type __n = __last - __first; 5373e519524SHoward Hinnant if (__n > 0) 5383e519524SHoward Hinnant { 5393e519524SHoward Hinnant // do first word 5403e519524SHoward Hinnant if (__last.__ctz_ != 0) 5413e519524SHoward Hinnant { 542ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n); 5433e519524SHoward Hinnant __n -= __dn; 5443e519524SHoward Hinnant unsigned __clz = __bits_per_word - __last.__ctz_; 5453e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); 5463e519524SHoward Hinnant __storage_type __b = *__last.__seg_ & __m; 5473e519524SHoward Hinnant *__result.__seg_ &= ~__m; 5483e519524SHoward Hinnant *__result.__seg_ |= __b; 5493e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + 5503e519524SHoward Hinnant __result.__ctz_) % __bits_per_word); 5513e519524SHoward Hinnant // __last.__ctz_ = 0 5523e519524SHoward Hinnant } 5533e519524SHoward Hinnant // __last.__ctz_ == 0 || __n == 0 5543e519524SHoward Hinnant // __result.__ctz_ == 0 || __n == 0 5553e519524SHoward Hinnant // do middle words 5563e519524SHoward Hinnant __storage_type __nw = __n / __bits_per_word; 5573e519524SHoward Hinnant __result.__seg_ -= __nw; 5583e519524SHoward Hinnant __last.__seg_ -= __nw; 559ce48a113SHoward Hinnant _VSTD::memmove(__result.__seg_, __last.__seg_, __nw * sizeof(__storage_type)); 5603e519524SHoward Hinnant __n -= __nw * __bits_per_word; 5613e519524SHoward Hinnant // do last word 5623e519524SHoward Hinnant if (__n > 0) 5633e519524SHoward Hinnant { 5643e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); 5653e519524SHoward Hinnant __storage_type __b = *--__last.__seg_ & __m; 5663e519524SHoward Hinnant *--__result.__seg_ &= ~__m; 5673e519524SHoward Hinnant *__result.__seg_ |= __b; 5683e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); 5693e519524SHoward Hinnant } 5703e519524SHoward Hinnant } 5713e519524SHoward Hinnant return __result; 5723e519524SHoward Hinnant} 5733e519524SHoward Hinnant 5743e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 5753e519524SHoward Hinnant__bit_iterator<_C, false> 5763e519524SHoward Hinnant__copy_backward_unaligned(__bit_iterator<_C, _IsConst> __first, __bit_iterator<_C, _IsConst> __last, 5773e519524SHoward Hinnant __bit_iterator<_C, false> __result) 5783e519524SHoward Hinnant{ 5793e519524SHoward Hinnant typedef __bit_iterator<_C, _IsConst> _In; 5803e519524SHoward Hinnant typedef typename _In::difference_type difference_type; 5813e519524SHoward Hinnant typedef typename _In::__storage_type __storage_type; 5823e519524SHoward Hinnant static const unsigned __bits_per_word = _In::__bits_per_word; 5833e519524SHoward Hinnant difference_type __n = __last - __first; 5843e519524SHoward Hinnant if (__n > 0) 5853e519524SHoward Hinnant { 5863e519524SHoward Hinnant // do first word 5873e519524SHoward Hinnant if (__last.__ctz_ != 0) 5883e519524SHoward Hinnant { 589ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n); 5903e519524SHoward Hinnant __n -= __dn; 5913e519524SHoward Hinnant unsigned __clz_l = __bits_per_word - __last.__ctz_; 5923e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); 5933e519524SHoward Hinnant __storage_type __b = *__last.__seg_ & __m; 5943e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 595ce48a113SHoward Hinnant __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_)); 5963e519524SHoward Hinnant if (__ddn > 0) 5973e519524SHoward Hinnant { 5983e519524SHoward Hinnant __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); 5993e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6003e519524SHoward Hinnant if (__result.__ctz_ > __last.__ctz_) 6013e519524SHoward Hinnant *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); 6023e519524SHoward Hinnant else 6033e519524SHoward Hinnant *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); 6043e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + 6053e519524SHoward Hinnant __result.__ctz_) % __bits_per_word); 6063e519524SHoward Hinnant __dn -= __ddn; 6073e519524SHoward Hinnant } 6083e519524SHoward Hinnant if (__dn > 0) 6093e519524SHoward Hinnant { 6103e519524SHoward Hinnant // __result.__ctz_ == 0 6113e519524SHoward Hinnant --__result.__seg_; 6123e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1)); 6133e519524SHoward Hinnant __m = ~__storage_type(0) << __result.__ctz_; 6143e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6153e519524SHoward Hinnant __last.__ctz_ -= __dn + __ddn; 6163e519524SHoward Hinnant *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); 6173e519524SHoward Hinnant } 6183e519524SHoward Hinnant // __last.__ctz_ = 0 6193e519524SHoward Hinnant } 6203e519524SHoward Hinnant // __last.__ctz_ == 0 || __n == 0 6213e519524SHoward Hinnant // __result.__ctz_ != 0 || __n == 0 6223e519524SHoward Hinnant // do middle words 6233e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 6243e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> __clz_r; 6253e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word) 6263e519524SHoward Hinnant { 6273e519524SHoward Hinnant __storage_type __b = *--__last.__seg_; 6283e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6293e519524SHoward Hinnant *__result.__seg_ |= __b >> __clz_r; 6303e519524SHoward Hinnant *--__result.__seg_ &= __m; 6313e519524SHoward Hinnant *__result.__seg_ |= __b << __result.__ctz_; 6323e519524SHoward Hinnant } 6333e519524SHoward Hinnant // do last word 6343e519524SHoward Hinnant if (__n > 0) 6353e519524SHoward Hinnant { 6363e519524SHoward Hinnant __m = ~__storage_type(0) << (__bits_per_word - __n); 6373e519524SHoward Hinnant __storage_type __b = *--__last.__seg_ & __m; 6383e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 639ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_)); 6403e519524SHoward Hinnant __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); 6413e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6423e519524SHoward Hinnant *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); 6433e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + 6443e519524SHoward Hinnant __result.__ctz_) % __bits_per_word); 6453e519524SHoward Hinnant __n -= __dn; 6463e519524SHoward Hinnant if (__n > 0) 6473e519524SHoward Hinnant { 6483e519524SHoward Hinnant // __result.__ctz_ == 0 6493e519524SHoward Hinnant --__result.__seg_; 6503e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); 6513e519524SHoward Hinnant __m = ~__storage_type(0) << __result.__ctz_; 6523e519524SHoward Hinnant *__result.__seg_ &= ~__m; 6533e519524SHoward Hinnant *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); 6543e519524SHoward Hinnant } 6553e519524SHoward Hinnant } 6563e519524SHoward Hinnant } 6573e519524SHoward Hinnant return __result; 6583e519524SHoward Hinnant} 6593e519524SHoward Hinnant 6603e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 6613e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 6623e519524SHoward Hinnant__bit_iterator<_C, false> 6633e519524SHoward Hinnantcopy_backward(__bit_iterator<_C, _IsConst> __first, __bit_iterator<_C, _IsConst> __last, __bit_iterator<_C, false> __result) 6643e519524SHoward Hinnant{ 6653e519524SHoward Hinnant if (__last.__ctz_ == __result.__ctz_) 6663e519524SHoward Hinnant return __copy_backward_aligned(__first, __last, __result); 6673e519524SHoward Hinnant return __copy_backward_unaligned(__first, __last, __result); 6683e519524SHoward Hinnant} 6693e519524SHoward Hinnant 6703e519524SHoward Hinnant// move 6713e519524SHoward Hinnant 6723e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 6733e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 6743e519524SHoward Hinnant__bit_iterator<_C, false> 6753e519524SHoward Hinnantmove(__bit_iterator<_C, _IsConst> __first, __bit_iterator<_C, _IsConst> __last, __bit_iterator<_C, false> __result) 6763e519524SHoward Hinnant{ 677ce48a113SHoward Hinnant return _VSTD::copy(__first, __last, __result); 6783e519524SHoward Hinnant} 6793e519524SHoward Hinnant 6803e519524SHoward Hinnant// move_backward 6813e519524SHoward Hinnant 6823e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 6833e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 6843e519524SHoward Hinnant__bit_iterator<_C, false> 6853e519524SHoward Hinnantmove_backward(__bit_iterator<_C, _IsConst> __first, __bit_iterator<_C, _IsConst> __last, __bit_iterator<_C, false> __result) 6863e519524SHoward Hinnant{ 687ce48a113SHoward Hinnant return _VSTD::copy(__first, __last, __result); 6883e519524SHoward Hinnant} 6893e519524SHoward Hinnant 6903e519524SHoward Hinnant// swap_ranges 6913e519524SHoward Hinnant 692dbe81119SHoward Hinnanttemplate <class __C1, class __C2> 693dbe81119SHoward Hinnant__bit_iterator<__C2, false> 694dbe81119SHoward Hinnant__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, 695dbe81119SHoward Hinnant __bit_iterator<__C2, false> __result) 6963e519524SHoward Hinnant{ 697dbe81119SHoward Hinnant typedef __bit_iterator<__C1, false> _I1; 6983e519524SHoward Hinnant typedef typename _I1::difference_type difference_type; 6993e519524SHoward Hinnant typedef typename _I1::__storage_type __storage_type; 7003e519524SHoward Hinnant static const unsigned __bits_per_word = _I1::__bits_per_word; 7013e519524SHoward Hinnant difference_type __n = __last - __first; 7023e519524SHoward Hinnant if (__n > 0) 7033e519524SHoward Hinnant { 7043e519524SHoward Hinnant // do first word 7053e519524SHoward Hinnant if (__first.__ctz_ != 0) 7063e519524SHoward Hinnant { 7073e519524SHoward Hinnant unsigned __clz = __bits_per_word - __first.__ctz_; 708ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 7093e519524SHoward Hinnant __n -= __dn; 7103e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 7113e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_ & __m; 7123e519524SHoward Hinnant *__first.__seg_ &= ~__m; 7133e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 7143e519524SHoward Hinnant *__result.__seg_ &= ~__m; 7153e519524SHoward Hinnant *__result.__seg_ |= __b1; 7163e519524SHoward Hinnant *__first.__seg_ |= __b2; 7173e519524SHoward Hinnant __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 7183e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 7193e519524SHoward Hinnant ++__first.__seg_; 7203e519524SHoward Hinnant // __first.__ctz_ = 0; 7213e519524SHoward Hinnant } 7223e519524SHoward Hinnant // __first.__ctz_ == 0; 7233e519524SHoward Hinnant // do middle words 7243e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) 7253e519524SHoward Hinnant swap(*__first.__seg_, *__result.__seg_); 7263e519524SHoward Hinnant // do last word 7273e519524SHoward Hinnant if (__n > 0) 7283e519524SHoward Hinnant { 7293e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 7303e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_ & __m; 7313e519524SHoward Hinnant *__first.__seg_ &= ~__m; 7323e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 7333e519524SHoward Hinnant *__result.__seg_ &= ~__m; 7343e519524SHoward Hinnant *__result.__seg_ |= __b1; 7353e519524SHoward Hinnant *__first.__seg_ |= __b2; 7363e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__n); 7373e519524SHoward Hinnant } 7383e519524SHoward Hinnant } 7393e519524SHoward Hinnant return __result; 7403e519524SHoward Hinnant} 7413e519524SHoward Hinnant 742dbe81119SHoward Hinnanttemplate <class __C1, class __C2> 743dbe81119SHoward Hinnant__bit_iterator<__C2, false> 744dbe81119SHoward Hinnant__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, 745dbe81119SHoward Hinnant __bit_iterator<__C2, false> __result) 7463e519524SHoward Hinnant{ 747dbe81119SHoward Hinnant typedef __bit_iterator<__C1, false> _I1; 7483e519524SHoward Hinnant typedef typename _I1::difference_type difference_type; 7493e519524SHoward Hinnant typedef typename _I1::__storage_type __storage_type; 7503e519524SHoward Hinnant static const unsigned __bits_per_word = _I1::__bits_per_word; 7513e519524SHoward Hinnant difference_type __n = __last - __first; 7523e519524SHoward Hinnant if (__n > 0) 7533e519524SHoward Hinnant { 7543e519524SHoward Hinnant // do first word 7553e519524SHoward Hinnant if (__first.__ctz_ != 0) 7563e519524SHoward Hinnant { 7573e519524SHoward Hinnant unsigned __clz_f = __bits_per_word - __first.__ctz_; 758ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 7593e519524SHoward Hinnant __n -= __dn; 7603e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 7613e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_ & __m; 7623e519524SHoward Hinnant *__first.__seg_ &= ~__m; 7633e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 764ce48a113SHoward Hinnant __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 7653e519524SHoward Hinnant __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 7663e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 7673e519524SHoward Hinnant *__result.__seg_ &= ~__m; 7683e519524SHoward Hinnant if (__result.__ctz_ > __first.__ctz_) 7693e519524SHoward Hinnant { 7703e519524SHoward Hinnant unsigned __s = __result.__ctz_ - __first.__ctz_; 7713e519524SHoward Hinnant *__result.__seg_ |= __b1 << __s; 7723e519524SHoward Hinnant *__first.__seg_ |= __b2 >> __s; 7733e519524SHoward Hinnant } 7743e519524SHoward Hinnant else 7753e519524SHoward Hinnant { 7763e519524SHoward Hinnant unsigned __s = __first.__ctz_ - __result.__ctz_; 7773e519524SHoward Hinnant *__result.__seg_ |= __b1 >> __s; 7783e519524SHoward Hinnant *__first.__seg_ |= __b2 << __s; 7793e519524SHoward Hinnant } 7803e519524SHoward Hinnant __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; 7813e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); 7823e519524SHoward Hinnant __dn -= __ddn; 7833e519524SHoward Hinnant if (__dn > 0) 7843e519524SHoward Hinnant { 7853e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __dn); 7863e519524SHoward Hinnant __b2 = *__result.__seg_ & __m; 7873e519524SHoward Hinnant *__result.__seg_ &= ~__m; 7883e519524SHoward Hinnant unsigned __s = __first.__ctz_ + __ddn; 7893e519524SHoward Hinnant *__result.__seg_ |= __b1 >> __s; 7903e519524SHoward Hinnant *__first.__seg_ |= __b2 << __s; 7913e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__dn); 7923e519524SHoward Hinnant } 7933e519524SHoward Hinnant ++__first.__seg_; 7943e519524SHoward Hinnant // __first.__ctz_ = 0; 7953e519524SHoward Hinnant } 7963e519524SHoward Hinnant // __first.__ctz_ == 0; 7973e519524SHoward Hinnant // do middle words 7983e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) << __result.__ctz_; 7993e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __result.__ctz_; 8003e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) 8013e519524SHoward Hinnant { 8023e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_; 8033e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 8043e519524SHoward Hinnant *__result.__seg_ &= ~__m; 8053e519524SHoward Hinnant *__result.__seg_ |= __b1 << __result.__ctz_; 8063e519524SHoward Hinnant *__first.__seg_ = __b2 >> __result.__ctz_; 8073e519524SHoward Hinnant ++__result.__seg_; 8083e519524SHoward Hinnant __b2 = *__result.__seg_ & ~__m; 8093e519524SHoward Hinnant *__result.__seg_ &= __m; 8103e519524SHoward Hinnant *__result.__seg_ |= __b1 >> __clz_r; 8113e519524SHoward Hinnant *__first.__seg_ |= __b2 << __clz_r; 8123e519524SHoward Hinnant } 8133e519524SHoward Hinnant // do last word 8143e519524SHoward Hinnant if (__n > 0) 8153e519524SHoward Hinnant { 8163e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 8173e519524SHoward Hinnant __storage_type __b1 = *__first.__seg_ & __m; 8183e519524SHoward Hinnant *__first.__seg_ &= ~__m; 819ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r); 8203e519524SHoward Hinnant __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 8213e519524SHoward Hinnant __storage_type __b2 = *__result.__seg_ & __m; 8223e519524SHoward Hinnant *__result.__seg_ &= ~__m; 8233e519524SHoward Hinnant *__result.__seg_ |= __b1 << __result.__ctz_; 8243e519524SHoward Hinnant *__first.__seg_ |= __b2 >> __result.__ctz_; 8253e519524SHoward Hinnant __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 8263e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 8273e519524SHoward Hinnant __n -= __dn; 8283e519524SHoward Hinnant if (__n > 0) 8293e519524SHoward Hinnant { 8303e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 8313e519524SHoward Hinnant __b2 = *__result.__seg_ & __m; 8323e519524SHoward Hinnant *__result.__seg_ &= ~__m; 8333e519524SHoward Hinnant *__result.__seg_ |= __b1 >> __dn; 8343e519524SHoward Hinnant *__first.__seg_ |= __b2 << __dn; 8353e519524SHoward Hinnant __result.__ctz_ = static_cast<unsigned>(__n); 8363e519524SHoward Hinnant } 8373e519524SHoward Hinnant } 8383e519524SHoward Hinnant } 8393e519524SHoward Hinnant return __result; 8403e519524SHoward Hinnant} 8413e519524SHoward Hinnant 842dbe81119SHoward Hinnanttemplate <class __C1, class __C2> 8433e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 844dbe81119SHoward Hinnant__bit_iterator<__C2, false> 845dbe81119SHoward Hinnantswap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, 846dbe81119SHoward Hinnant __bit_iterator<__C2, false> __first2) 8473e519524SHoward Hinnant{ 8483e519524SHoward Hinnant if (__first1.__ctz_ == __first2.__ctz_) 8493e519524SHoward Hinnant return __swap_ranges_aligned(__first1, __last1, __first2); 8503e519524SHoward Hinnant return __swap_ranges_unaligned(__first1, __last1, __first2); 8513e519524SHoward Hinnant} 8523e519524SHoward Hinnant 8533e519524SHoward Hinnant// rotate 8543e519524SHoward Hinnant 8553e519524SHoward Hinnanttemplate <class _C> 8563e519524SHoward Hinnantstruct __bit_array 8573e519524SHoward Hinnant{ 8583e519524SHoward Hinnant typedef typename _C::difference_type difference_type; 8593e519524SHoward Hinnant typedef typename _C::__storage_type __storage_type; 8603e519524SHoward Hinnant typedef typename _C::iterator iterator; 8613e519524SHoward Hinnant static const unsigned __bits_per_word = _C::__bits_per_word; 8623e519524SHoward Hinnant static const unsigned _N = 4; 8633e519524SHoward Hinnant 8643e519524SHoward Hinnant difference_type __size_; 8653e519524SHoward Hinnant __storage_type __word_[_N]; 8663e519524SHoward Hinnant 8673e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY static difference_type capacity() 8683e519524SHoward Hinnant {return static_cast<difference_type>(_N * __bits_per_word);} 8693e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {} 8703e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY iterator begin() {return iterator(__word_, 0);} 8713e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY iterator end() {return iterator(__word_ + __size_ / __bits_per_word, 8723e519524SHoward Hinnant static_cast<unsigned>(__size_ % __bits_per_word));} 8733e519524SHoward Hinnant}; 8743e519524SHoward Hinnant 8753e519524SHoward Hinnanttemplate <class _C> 8763e519524SHoward Hinnant__bit_iterator<_C, false> 8773e519524SHoward Hinnantrotate(__bit_iterator<_C, false> __first, __bit_iterator<_C, false> __middle, __bit_iterator<_C, false> __last) 8783e519524SHoward Hinnant{ 8793e519524SHoward Hinnant typedef __bit_iterator<_C, false> _I1; 8803e519524SHoward Hinnant typedef typename _I1::difference_type difference_type; 8813e519524SHoward Hinnant typedef typename _I1::__storage_type __storage_type; 8823e519524SHoward Hinnant static const unsigned __bits_per_word = _I1::__bits_per_word; 8833e519524SHoward Hinnant difference_type __d1 = __middle - __first; 8843e519524SHoward Hinnant difference_type __d2 = __last - __middle; 8853e519524SHoward Hinnant _I1 __r = __first + __d2; 8863e519524SHoward Hinnant while (__d1 != 0 && __d2 != 0) 8873e519524SHoward Hinnant { 8883e519524SHoward Hinnant if (__d1 <= __d2) 8893e519524SHoward Hinnant { 8903e519524SHoward Hinnant if (__d1 <= __bit_array<_C>::capacity()) 8913e519524SHoward Hinnant { 8923e519524SHoward Hinnant __bit_array<_C> __b(__d1); 893ce48a113SHoward Hinnant _VSTD::copy(__first, __middle, __b.begin()); 894ce48a113SHoward Hinnant _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first)); 8953e519524SHoward Hinnant break; 8963e519524SHoward Hinnant } 8973e519524SHoward Hinnant else 8983e519524SHoward Hinnant { 899ce48a113SHoward Hinnant __bit_iterator<_C, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle); 9003e519524SHoward Hinnant __first = __middle; 9013e519524SHoward Hinnant __middle = __mp; 9023e519524SHoward Hinnant __d2 -= __d1; 9033e519524SHoward Hinnant } 9043e519524SHoward Hinnant } 9053e519524SHoward Hinnant else 9063e519524SHoward Hinnant { 9073e519524SHoward Hinnant if (__d2 <= __bit_array<_C>::capacity()) 9083e519524SHoward Hinnant { 9093e519524SHoward Hinnant __bit_array<_C> __b(__d2); 910ce48a113SHoward Hinnant _VSTD::copy(__middle, __last, __b.begin()); 911ce48a113SHoward Hinnant _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last)); 9123e519524SHoward Hinnant break; 9133e519524SHoward Hinnant } 9143e519524SHoward Hinnant else 9153e519524SHoward Hinnant { 9163e519524SHoward Hinnant __bit_iterator<_C, false> __mp = __first + __d2; 917ce48a113SHoward Hinnant _VSTD::swap_ranges(__first, __mp, __middle); 9183e519524SHoward Hinnant __first = __mp; 9193e519524SHoward Hinnant __d1 -= __d2; 9203e519524SHoward Hinnant } 9213e519524SHoward Hinnant } 9223e519524SHoward Hinnant } 9233e519524SHoward Hinnant return __r; 9243e519524SHoward Hinnant} 9253e519524SHoward Hinnant 9263e519524SHoward Hinnant// equal 9273e519524SHoward Hinnant 9283e519524SHoward Hinnanttemplate <class _C> 9293e519524SHoward Hinnantbool 9303e519524SHoward Hinnant__equal_unaligned(__bit_iterator<_C, true> __first1, __bit_iterator<_C, true> __last1, 9313e519524SHoward Hinnant __bit_iterator<_C, true> __first2) 9323e519524SHoward Hinnant{ 9333e519524SHoward Hinnant typedef __bit_iterator<_C, true> _It; 9343e519524SHoward Hinnant typedef typename _It::difference_type difference_type; 9353e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 9363e519524SHoward Hinnant static const unsigned __bits_per_word = _It::__bits_per_word; 9373e519524SHoward Hinnant difference_type __n = __last1 - __first1; 9383e519524SHoward Hinnant if (__n > 0) 9393e519524SHoward Hinnant { 9403e519524SHoward Hinnant // do first word 9413e519524SHoward Hinnant if (__first1.__ctz_ != 0) 9423e519524SHoward Hinnant { 9433e519524SHoward Hinnant unsigned __clz_f = __bits_per_word - __first1.__ctz_; 944ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 9453e519524SHoward Hinnant __n -= __dn; 9463e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 9473e519524SHoward Hinnant __storage_type __b = *__first1.__seg_ & __m; 9483e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __first2.__ctz_; 949ce48a113SHoward Hinnant __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 9503e519524SHoward Hinnant __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 9513e519524SHoward Hinnant if (__first2.__ctz_ > __first1.__ctz_) 9523e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) 9533e519524SHoward Hinnant return false; 9543e519524SHoward Hinnant else 9553e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) 9563e519524SHoward Hinnant return false; 9573e519524SHoward Hinnant __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; 9583e519524SHoward Hinnant __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word); 9593e519524SHoward Hinnant __dn -= __ddn; 9603e519524SHoward Hinnant if (__dn > 0) 9613e519524SHoward Hinnant { 9623e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __dn); 9633e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) 9643e519524SHoward Hinnant return false; 9653e519524SHoward Hinnant __first2.__ctz_ = static_cast<unsigned>(__dn); 9663e519524SHoward Hinnant } 9673e519524SHoward Hinnant ++__first1.__seg_; 9683e519524SHoward Hinnant // __first1.__ctz_ = 0; 9693e519524SHoward Hinnant } 9703e519524SHoward Hinnant // __first1.__ctz_ == 0; 9713e519524SHoward Hinnant // do middle words 9723e519524SHoward Hinnant unsigned __clz_r = __bits_per_word - __first2.__ctz_; 9733e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) << __first2.__ctz_; 9743e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) 9753e519524SHoward Hinnant { 9763e519524SHoward Hinnant __storage_type __b = *__first1.__seg_; 9773e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) 9783e519524SHoward Hinnant return false; 9793e519524SHoward Hinnant ++__first2.__seg_; 9803e519524SHoward Hinnant if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) 9813e519524SHoward Hinnant return false; 9823e519524SHoward Hinnant } 9833e519524SHoward Hinnant // do last word 9843e519524SHoward Hinnant if (__n > 0) 9853e519524SHoward Hinnant { 9863e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 9873e519524SHoward Hinnant __storage_type __b = *__first1.__seg_ & __m; 988ce48a113SHoward Hinnant __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r)); 9893e519524SHoward Hinnant __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 9903e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) 9913e519524SHoward Hinnant return false; 9923e519524SHoward Hinnant __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; 9933e519524SHoward Hinnant __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word); 9943e519524SHoward Hinnant __n -= __dn; 9953e519524SHoward Hinnant if (__n > 0) 9963e519524SHoward Hinnant { 9973e519524SHoward Hinnant __m = ~__storage_type(0) >> (__bits_per_word - __n); 9983e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (__b >> __dn)) 9993e519524SHoward Hinnant return false; 10003e519524SHoward Hinnant } 10013e519524SHoward Hinnant } 10023e519524SHoward Hinnant } 10033e519524SHoward Hinnant return true; 10043e519524SHoward Hinnant} 10053e519524SHoward Hinnant 10063e519524SHoward Hinnanttemplate <class _C> 10073e519524SHoward Hinnantbool 10083e519524SHoward Hinnant__equal_aligned(__bit_iterator<_C, true> __first1, __bit_iterator<_C, true> __last1, 10093e519524SHoward Hinnant __bit_iterator<_C, true> __first2) 10103e519524SHoward Hinnant{ 10113e519524SHoward Hinnant typedef __bit_iterator<_C, true> _It; 10123e519524SHoward Hinnant typedef typename _It::difference_type difference_type; 10133e519524SHoward Hinnant typedef typename _It::__storage_type __storage_type; 10143e519524SHoward Hinnant static const unsigned __bits_per_word = _It::__bits_per_word; 10153e519524SHoward Hinnant difference_type __n = __last1 - __first1; 10163e519524SHoward Hinnant if (__n > 0) 10173e519524SHoward Hinnant { 10183e519524SHoward Hinnant // do first word 10193e519524SHoward Hinnant if (__first1.__ctz_ != 0) 10203e519524SHoward Hinnant { 10213e519524SHoward Hinnant unsigned __clz = __bits_per_word - __first1.__ctz_; 1022ce48a113SHoward Hinnant difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 10233e519524SHoward Hinnant __n -= __dn; 10243e519524SHoward Hinnant __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 10253e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) 10263e519524SHoward Hinnant return false; 10273e519524SHoward Hinnant ++__first2.__seg_; 10283e519524SHoward Hinnant ++__first1.__seg_; 10293e519524SHoward Hinnant // __first1.__ctz_ = 0; 10303e519524SHoward Hinnant // __first2.__ctz_ = 0; 10313e519524SHoward Hinnant } 10323e519524SHoward Hinnant // __first1.__ctz_ == 0; 10333e519524SHoward Hinnant // __first2.__ctz_ == 0; 10343e519524SHoward Hinnant // do middle words 10353e519524SHoward Hinnant for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) 10363e519524SHoward Hinnant if (*__first2.__seg_ != *__first1.__seg_) 10373e519524SHoward Hinnant return false; 10383e519524SHoward Hinnant // do last word 10393e519524SHoward Hinnant if (__n > 0) 10403e519524SHoward Hinnant { 10413e519524SHoward Hinnant __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 10423e519524SHoward Hinnant if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) 10433e519524SHoward Hinnant return false; 10443e519524SHoward Hinnant } 10453e519524SHoward Hinnant } 10463e519524SHoward Hinnant return true; 10473e519524SHoward Hinnant} 10483e519524SHoward Hinnant 10493e519524SHoward Hinnanttemplate <class _C, bool _IC1, bool _IC2> 105043d99238SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 10513e519524SHoward Hinnantbool 10523e519524SHoward Hinnantequal(__bit_iterator<_C, _IC1> __first1, __bit_iterator<_C, _IC1> __last1, __bit_iterator<_C, _IC2> __first2) 10533e519524SHoward Hinnant{ 10543e519524SHoward Hinnant if (__first1.__ctz_ == __first2.__ctz_) 10553e519524SHoward Hinnant return __equal_aligned(__first1, __last1, __first2); 10563e519524SHoward Hinnant return __equal_unaligned(__first1, __last1, __first2); 10573e519524SHoward Hinnant} 10583e519524SHoward Hinnant 10593e519524SHoward Hinnanttemplate <class _C, bool _IsConst> 10603e519524SHoward Hinnantclass __bit_iterator 10613e519524SHoward Hinnant{ 10623e519524SHoward Hinnantpublic: 10633e519524SHoward Hinnant typedef typename _C::difference_type difference_type; 10643e519524SHoward Hinnant typedef bool value_type; 10653e519524SHoward Hinnant typedef __bit_iterator pointer; 10663e519524SHoward Hinnant typedef typename conditional<_IsConst, __bit_const_reference<_C>, __bit_reference<_C> >::type reference; 10673e519524SHoward Hinnant typedef random_access_iterator_tag iterator_category; 10683e519524SHoward Hinnant 10693e519524SHoward Hinnantprivate: 10703e519524SHoward Hinnant typedef typename _C::__storage_type __storage_type; 10713e519524SHoward Hinnant typedef typename conditional<_IsConst, typename _C::__const_storage_pointer, 10723e519524SHoward Hinnant typename _C::__storage_pointer>::type __storage_pointer; 10733e519524SHoward Hinnant static const unsigned __bits_per_word = _C::__bits_per_word; 10743e519524SHoward Hinnant 10753e519524SHoward Hinnant __storage_pointer __seg_; 10763e519524SHoward Hinnant unsigned __ctz_; 10773e519524SHoward Hinnant 10783e519524SHoward Hinnantpublic: 1079d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT {} 10803e519524SHoward Hinnant 1081d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1082d368a84cSHoward Hinnant __bit_iterator(const __bit_iterator<_C, false>& __it) _NOEXCEPT 10833e519524SHoward Hinnant : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} 10843e519524SHoward Hinnant 1085d368a84cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT 1086d368a84cSHoward Hinnant {return reference(__seg_, __storage_type(1) << __ctz_);} 10873e519524SHoward Hinnant 10883e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++() 10893e519524SHoward Hinnant { 10903e519524SHoward Hinnant if (__ctz_ != __bits_per_word-1) 10913e519524SHoward Hinnant ++__ctz_; 10923e519524SHoward Hinnant else 10933e519524SHoward Hinnant { 10943e519524SHoward Hinnant __ctz_ = 0; 10953e519524SHoward Hinnant ++__seg_; 10963e519524SHoward Hinnant } 10973e519524SHoward Hinnant return *this; 10983e519524SHoward Hinnant } 10993e519524SHoward Hinnant 11003e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int) 11013e519524SHoward Hinnant { 11023e519524SHoward Hinnant __bit_iterator __tmp = *this; 11033e519524SHoward Hinnant ++(*this); 11043e519524SHoward Hinnant return __tmp; 11053e519524SHoward Hinnant } 11063e519524SHoward Hinnant 11073e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--() 11083e519524SHoward Hinnant { 11093e519524SHoward Hinnant if (__ctz_ != 0) 11103e519524SHoward Hinnant --__ctz_; 11113e519524SHoward Hinnant else 11123e519524SHoward Hinnant { 11133e519524SHoward Hinnant __ctz_ = __bits_per_word - 1; 11143e519524SHoward Hinnant --__seg_; 11153e519524SHoward Hinnant } 11163e519524SHoward Hinnant return *this; 11173e519524SHoward Hinnant } 11183e519524SHoward Hinnant 11193e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int) 11203e519524SHoward Hinnant { 11213e519524SHoward Hinnant __bit_iterator __tmp = *this; 11223e519524SHoward Hinnant --(*this); 11233e519524SHoward Hinnant return __tmp; 11243e519524SHoward Hinnant } 11253e519524SHoward Hinnant 11263e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n) 11273e519524SHoward Hinnant { 11283e519524SHoward Hinnant if (__n >= 0) 11293e519524SHoward Hinnant __seg_ += (__n + __ctz_) / __bits_per_word; 11303e519524SHoward Hinnant else 11313e519524SHoward Hinnant __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) 11323e519524SHoward Hinnant / static_cast<difference_type>(__bits_per_word); 11333e519524SHoward Hinnant __n &= (__bits_per_word - 1); 11343e519524SHoward Hinnant __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word); 11353e519524SHoward Hinnant return *this; 11363e519524SHoward Hinnant } 11373e519524SHoward Hinnant 11383e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n) 11393e519524SHoward Hinnant { 11403e519524SHoward Hinnant return *this += -__n; 11413e519524SHoward Hinnant } 11423e519524SHoward Hinnant 11433e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const 11443e519524SHoward Hinnant { 11453e519524SHoward Hinnant __bit_iterator __t(*this); 11463e519524SHoward Hinnant __t += __n; 11473e519524SHoward Hinnant return __t; 11483e519524SHoward Hinnant } 11493e519524SHoward Hinnant 11503e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const 11513e519524SHoward Hinnant { 11523e519524SHoward Hinnant __bit_iterator __t(*this); 11533e519524SHoward Hinnant __t -= __n; 11543e519524SHoward Hinnant return __t; 11553e519524SHoward Hinnant } 11563e519524SHoward Hinnant 11573e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 11583e519524SHoward Hinnant friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;} 11593e519524SHoward Hinnant 11603e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 11613e519524SHoward Hinnant friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) 11623e519524SHoward Hinnant {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;} 11633e519524SHoward Hinnant 11643e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);} 11653e519524SHoward Hinnant 11663e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) 11673e519524SHoward Hinnant {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;} 11683e519524SHoward Hinnant 11693e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) 11703e519524SHoward Hinnant {return !(__x == __y);} 11713e519524SHoward Hinnant 11723e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) 11733e519524SHoward Hinnant {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);} 11743e519524SHoward Hinnant 11753e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) 11763e519524SHoward Hinnant {return __y < __x;} 11773e519524SHoward Hinnant 11783e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) 11793e519524SHoward Hinnant {return !(__y < __x);} 11803e519524SHoward Hinnant 11813e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) 11823e519524SHoward Hinnant {return !(__x < __y);} 11833e519524SHoward Hinnant 11843e519524SHoward Hinnantprivate: 11853e519524SHoward Hinnant _LIBCPP_INLINE_VISIBILITY 1186d368a84cSHoward Hinnant __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT 1187d368a84cSHoward Hinnant : __seg_(__s), __ctz_(__ctz) {} 11883e519524SHoward Hinnant 11893e519524SHoward Hinnant#if defined(__clang__) 11903e519524SHoward Hinnant friend typename _C::__self; 11913e519524SHoward Hinnant#else 11923e519524SHoward Hinnant friend class _C::__self; 11933e519524SHoward Hinnant#endif 11943e519524SHoward Hinnant friend class __bit_reference<_C>; 11953e519524SHoward Hinnant friend class __bit_const_reference<_C>; 11963e519524SHoward Hinnant friend class __bit_iterator<_C, true>; 11973e519524SHoward Hinnant template <class _D> friend struct __bit_array; 11983e519524SHoward Hinnant template <class _D> friend void __fill_n_false(__bit_iterator<_D, false> __first, typename _D::size_type __n); 11993e519524SHoward Hinnant template <class _D> friend void __fill_n_true(__bit_iterator<_D, false> __first, typename _D::size_type __n); 12003e519524SHoward Hinnant template <class _D, bool _IC> friend __bit_iterator<_D, false> __copy_aligned(__bit_iterator<_D, _IC> __first, 12013e519524SHoward Hinnant __bit_iterator<_D, _IC> __last, 12023e519524SHoward Hinnant __bit_iterator<_D, false> __result); 12033e519524SHoward Hinnant template <class _D, bool _IC> friend __bit_iterator<_D, false> __copy_unaligned(__bit_iterator<_D, _IC> __first, 12043e519524SHoward Hinnant __bit_iterator<_D, _IC> __last, 12053e519524SHoward Hinnant __bit_iterator<_D, false> __result); 12063e519524SHoward Hinnant template <class _D, bool _IC> friend __bit_iterator<_D, false> copy(__bit_iterator<_D, _IC> __first, 12073e519524SHoward Hinnant __bit_iterator<_D, _IC> __last, 12083e519524SHoward Hinnant __bit_iterator<_D, false> __result); 12093e519524SHoward Hinnant template <class _D, bool _IC> friend __bit_iterator<_D, false> __copy_backward_aligned(__bit_iterator<_D, _IC> __first, 12103e519524SHoward Hinnant __bit_iterator<_D, _IC> __last, 12113e519524SHoward Hinnant __bit_iterator<_D, false> __result); 12123e519524SHoward Hinnant template <class _D, bool _IC> friend __bit_iterator<_D, false> __copy_backward_unaligned(__bit_iterator<_D, _IC> __first, 12133e519524SHoward Hinnant __bit_iterator<_D, _IC> __last, 12143e519524SHoward Hinnant __bit_iterator<_D, false> __result); 12153e519524SHoward Hinnant template <class _D, bool _IC> friend __bit_iterator<_D, false> copy_backward(__bit_iterator<_D, _IC> __first, 12163e519524SHoward Hinnant __bit_iterator<_D, _IC> __last, 12173e519524SHoward Hinnant __bit_iterator<_D, false> __result); 1218dbe81119SHoward Hinnant template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, 1219dbe81119SHoward Hinnant __bit_iterator<__C1, false>, 1220dbe81119SHoward Hinnant __bit_iterator<__C2, false>); 1221dbe81119SHoward Hinnant template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>, 1222dbe81119SHoward Hinnant __bit_iterator<__C1, false>, 1223dbe81119SHoward Hinnant __bit_iterator<__C2, false>); 1224dbe81119SHoward Hinnant template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, 1225dbe81119SHoward Hinnant __bit_iterator<__C1, false>, 1226dbe81119SHoward Hinnant __bit_iterator<__C2, false>); 12273e519524SHoward Hinnant template <class _D> friend __bit_iterator<_D, false> rotate(__bit_iterator<_D, false>, 12283e519524SHoward Hinnant __bit_iterator<_D, false>, 12293e519524SHoward Hinnant __bit_iterator<_D, false>); 12303e519524SHoward Hinnant template <class _D> friend bool __equal_aligned(__bit_iterator<_D, true>, 12313e519524SHoward Hinnant __bit_iterator<_D, true>, 12323e519524SHoward Hinnant __bit_iterator<_D, true>); 12333e519524SHoward Hinnant template <class _D> friend bool __equal_unaligned(__bit_iterator<_D, true>, 12343e519524SHoward Hinnant __bit_iterator<_D, true>, 12353e519524SHoward Hinnant __bit_iterator<_D, true>); 12363e519524SHoward Hinnant template <class _D, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_D, _IC1>, 12373e519524SHoward Hinnant __bit_iterator<_D, _IC1>, 12383e519524SHoward Hinnant __bit_iterator<_D, _IC2>); 12393e519524SHoward Hinnant template <class _D> friend __bit_iterator<_D, false> __find_bool_true(__bit_iterator<_D, false>, 12403e519524SHoward Hinnant typename _D::size_type); 12413e519524SHoward Hinnant template <class _D> friend __bit_iterator<_D, false> __find_bool_false(__bit_iterator<_D, false>, 12423e519524SHoward Hinnant typename _D::size_type); 12433e519524SHoward Hinnant}; 12443e519524SHoward Hinnant 12453e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD 12463e519524SHoward Hinnant 12473e519524SHoward Hinnant#endif // _LIBCPP___BIT_REFERENCE 1248