13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP___BIT_REFERENCE
113e519524SHoward Hinnant#define _LIBCPP___BIT_REFERENCE
123e519524SHoward Hinnant
132e2f3158SNikolas Klauser#include <__algorithm/min.h>
14b973e2e2SThorsten Schütt#include <__bits>
154d81a46fSArthur O'Dwyer#include <__config>
162e2f3158SNikolas Klauser#include <__iterator/iterator_traits.h>
172e2f3158SNikolas Klauser#include <__memory/pointer_traits.h>
182e2f3158SNikolas Klauser#include <cstring>
192e2f3158SNikolas Klauser#include <type_traits>
203e519524SHoward Hinnant
21073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
223e519524SHoward Hinnant#  pragma GCC system_header
23073458b1SHoward Hinnant#endif
243e519524SHoward Hinnant
25a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS
26a016efb1SEric Fiselier#include <__undef_macros>
27a016efb1SEric Fiselier
28a016efb1SEric Fiselier
293e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
303e519524SHoward Hinnant
310ae9efebSHoward Hinnanttemplate <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;
32c003db1fSHoward Hinnanttemplate <class _Cp> class __bit_const_reference;
333e519524SHoward Hinnant
34a7744562SHoward Hinnanttemplate <class _Tp>
35a7744562SHoward Hinnantstruct __has_storage_type
36a7744562SHoward Hinnant{
37a7744562SHoward Hinnant    static const bool value = false;
38a7744562SHoward Hinnant};
39a7744562SHoward Hinnant
40c003db1fSHoward Hinnanttemplate <class _Cp, bool = __has_storage_type<_Cp>::value>
413e519524SHoward Hinnantclass __bit_reference
423e519524SHoward Hinnant{
43c003db1fSHoward Hinnant    typedef typename _Cp::__storage_type    __storage_type;
44c003db1fSHoward Hinnant    typedef typename _Cp::__storage_pointer __storage_pointer;
453e519524SHoward Hinnant
463e519524SHoward Hinnant    __storage_pointer __seg_;
473e519524SHoward Hinnant    __storage_type    __mask_;
483e519524SHoward Hinnant
49c003db1fSHoward Hinnant    friend typename _Cp::__self;
50541f9e28SEric Fiselier
51c003db1fSHoward Hinnant    friend class __bit_const_reference<_Cp>;
52c003db1fSHoward Hinnant    friend class __bit_iterator<_Cp, false>;
533e519524SHoward Hinnantpublic:
54b7eb30d4SFangrui Song    _LIBCPP_INLINE_VISIBILITY
55b7eb30d4SFangrui Song    __bit_reference(const __bit_reference&) = default;
56b7eb30d4SFangrui Song
57d368a84cSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
58d368a84cSHoward Hinnant        {return static_cast<bool>(*__seg_ & __mask_);}
59d368a84cSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT
60d368a84cSHoward Hinnant        {return !static_cast<bool>(*this);}
613e519524SHoward Hinnant
623e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
63d368a84cSHoward Hinnant    __bit_reference& operator=(bool __x) _NOEXCEPT
643e519524SHoward Hinnant    {
653e519524SHoward Hinnant        if (__x)
663e519524SHoward Hinnant            *__seg_ |= __mask_;
673e519524SHoward Hinnant        else
683e519524SHoward Hinnant            *__seg_ &= ~__mask_;
693e519524SHoward Hinnant        return *this;
703e519524SHoward Hinnant    }
713e519524SHoward Hinnant
72fb9646edSNikolas Klauser#if _LIBCPP_STD_VER > 20
73fb9646edSNikolas Klauser    _LIBCPP_HIDE_FROM_ABI const __bit_reference& operator=(bool __x) const noexcept {
74fb9646edSNikolas Klauser        if (__x)
75fb9646edSNikolas Klauser            *__seg_ |= __mask_;
76fb9646edSNikolas Klauser        else
77fb9646edSNikolas Klauser            *__seg_ &= ~__mask_;
78fb9646edSNikolas Klauser        return *this;
79fb9646edSNikolas Klauser    }
80fb9646edSNikolas Klauser#endif
81fb9646edSNikolas Klauser
823e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
83d368a84cSHoward Hinnant    __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
84d368a84cSHoward Hinnant        {return operator=(static_cast<bool>(__x));}
853e519524SHoward Hinnant
86d368a84cSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
87c003db1fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
88f3b851f0SMarshall Clow        {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
893e519524SHoward Hinnantprivate:
903e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
91*f86c2b6fSArthur O'Dwyer    explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
92d368a84cSHoward Hinnant        : __seg_(__s), __mask_(__m) {}
933e519524SHoward Hinnant};
943e519524SHoward Hinnant
95c003db1fSHoward Hinnanttemplate <class _Cp>
96c003db1fSHoward Hinnantclass __bit_reference<_Cp, false>
97a7744562SHoward Hinnant{
98a7744562SHoward Hinnant};
99a7744562SHoward Hinnant
100d9db9f90SHoward Hinnanttemplate <class _Cp>
1013af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
102d9db9f90SHoward Hinnantvoid
103d9db9f90SHoward Hinnantswap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
104d9db9f90SHoward Hinnant{
105d9db9f90SHoward Hinnant    bool __t = __x;
106d9db9f90SHoward Hinnant    __x = __y;
107d9db9f90SHoward Hinnant    __y = __t;
108d9db9f90SHoward Hinnant}
109d9db9f90SHoward Hinnant
110c003db1fSHoward Hinnanttemplate <class _Cp, class _Dp>
1113af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1123e519524SHoward Hinnantvoid
113c003db1fSHoward Hinnantswap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
1143e519524SHoward Hinnant{
1153e519524SHoward Hinnant    bool __t = __x;
1163e519524SHoward Hinnant    __x = __y;
1173e519524SHoward Hinnant    __y = __t;
1183e519524SHoward Hinnant}
1193e519524SHoward Hinnant
120c003db1fSHoward Hinnanttemplate <class _Cp>
1213af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1223e519524SHoward Hinnantvoid
123c003db1fSHoward Hinnantswap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
1243e519524SHoward Hinnant{
1253e519524SHoward Hinnant    bool __t = __x;
1263e519524SHoward Hinnant    __x = __y;
1273e519524SHoward Hinnant    __y = __t;
1283e519524SHoward Hinnant}
1293e519524SHoward Hinnant
130c003db1fSHoward Hinnanttemplate <class _Cp>
1313af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
1323e519524SHoward Hinnantvoid
133c003db1fSHoward Hinnantswap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
1343e519524SHoward Hinnant{
1353e519524SHoward Hinnant    bool __t = __x;
1363e519524SHoward Hinnant    __x = __y;
1373e519524SHoward Hinnant    __y = __t;
1383e519524SHoward Hinnant}
1393e519524SHoward Hinnant
140c003db1fSHoward Hinnanttemplate <class _Cp>
1413e519524SHoward Hinnantclass __bit_const_reference
1423e519524SHoward Hinnant{
143c003db1fSHoward Hinnant    typedef typename _Cp::__storage_type          __storage_type;
144c003db1fSHoward Hinnant    typedef typename _Cp::__const_storage_pointer __storage_pointer;
1453e519524SHoward Hinnant
1463e519524SHoward Hinnant    __storage_pointer        __seg_;
1473e519524SHoward Hinnant    __storage_type __mask_;
1483e519524SHoward Hinnant
149c003db1fSHoward Hinnant    friend typename _Cp::__self;
150c003db1fSHoward Hinnant    friend class __bit_iterator<_Cp, true>;
1513e519524SHoward Hinnantpublic:
1523e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
153b7eb30d4SFangrui Song    __bit_const_reference(const __bit_const_reference&) = default;
154b7eb30d4SFangrui Song
155b7eb30d4SFangrui Song    _LIBCPP_INLINE_VISIBILITY
156c003db1fSHoward Hinnant    __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
1573e519524SHoward Hinnant        : __seg_(__x.__seg_), __mask_(__x.__mask_) {}
1583e519524SHoward Hinnant
159eeac9fcfSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT
160d368a84cSHoward Hinnant        {return static_cast<bool>(*__seg_ & __mask_);}
1613e519524SHoward Hinnant
162c003db1fSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
163f3b851f0SMarshall Clow        {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
1643e519524SHoward Hinnantprivate:
1653e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
166eeac9fcfSHoward Hinnant    _LIBCPP_CONSTEXPR
167*f86c2b6fSArthur O'Dwyer    explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
168d368a84cSHoward Hinnant        : __seg_(__s), __mask_(__m) {}
1693e519524SHoward Hinnant
170b7eb30d4SFangrui Song    __bit_const_reference& operator=(const __bit_const_reference&) = delete;
1713e519524SHoward Hinnant};
1723e519524SHoward Hinnant
1733e519524SHoward Hinnant// find
1743e519524SHoward Hinnant
175423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst>
176423a8d77SHoward Hinnant__bit_iterator<_Cp, _IsConst>
177423a8d77SHoward Hinnant__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
1783e519524SHoward Hinnant{
179423a8d77SHoward Hinnant    typedef __bit_iterator<_Cp, _IsConst> _It;
1803e519524SHoward Hinnant    typedef typename _It::__storage_type __storage_type;
181aec08784SEric Fiselier    static const int __bits_per_word = _It::__bits_per_word;
1823e519524SHoward Hinnant    // do first partial word
1833e519524SHoward Hinnant    if (__first.__ctz_ != 0)
1843e519524SHoward Hinnant    {
1853e519524SHoward Hinnant        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
186ce48a113SHoward Hinnant        __storage_type __dn = _VSTD::min(__clz_f, __n);
1873e519524SHoward Hinnant        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
1883e519524SHoward Hinnant        __storage_type __b = *__first.__seg_ & __m;
1893e519524SHoward Hinnant        if (__b)
190f3b851f0SMarshall Clow            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
191303e27d8SHoward Hinnant        if (__n == __dn)
1920fc6e981SMarshall Clow            return __first + __n;
1933e519524SHoward Hinnant        __n -= __dn;
1943e519524SHoward Hinnant        ++__first.__seg_;
1953e519524SHoward Hinnant    }
1963e519524SHoward Hinnant    // do middle whole words
1973e519524SHoward Hinnant    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
1983e519524SHoward Hinnant        if (*__first.__seg_)
199f3b851f0SMarshall Clow            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(*__first.__seg_)));
2003e519524SHoward Hinnant    // do last partial word
2013e519524SHoward Hinnant    if (__n > 0)
2023e519524SHoward Hinnant    {
2033e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
2043e519524SHoward Hinnant        __storage_type __b = *__first.__seg_ & __m;
2053e519524SHoward Hinnant        if (__b)
206f3b851f0SMarshall Clow            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
2073e519524SHoward Hinnant    }
2083e519524SHoward Hinnant    return _It(__first.__seg_, static_cast<unsigned>(__n));
2093e519524SHoward Hinnant}
2103e519524SHoward Hinnant
211423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst>
212423a8d77SHoward Hinnant__bit_iterator<_Cp, _IsConst>
213423a8d77SHoward Hinnant__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
2143e519524SHoward Hinnant{
215423a8d77SHoward Hinnant    typedef __bit_iterator<_Cp, _IsConst> _It;
2163e519524SHoward Hinnant    typedef typename _It::__storage_type __storage_type;
217aec08784SEric Fiselier    const int __bits_per_word = _It::__bits_per_word;
2183e519524SHoward Hinnant    // do first partial word
2193e519524SHoward Hinnant    if (__first.__ctz_ != 0)
2203e519524SHoward Hinnant    {
2213e519524SHoward Hinnant        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
222ce48a113SHoward Hinnant        __storage_type __dn = _VSTD::min(__clz_f, __n);
2233e519524SHoward Hinnant        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
224423a8d77SHoward Hinnant        __storage_type __b = ~*__first.__seg_ & __m;
2253e519524SHoward Hinnant        if (__b)
226f3b851f0SMarshall Clow            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
227303e27d8SHoward Hinnant        if (__n == __dn)
2280fc6e981SMarshall Clow            return __first + __n;
2293e519524SHoward Hinnant        __n -= __dn;
2303e519524SHoward Hinnant        ++__first.__seg_;
2313e519524SHoward Hinnant    }
2323e519524SHoward Hinnant    // do middle whole words
2333e519524SHoward Hinnant    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
2343e519524SHoward Hinnant    {
2353e519524SHoward Hinnant        __storage_type __b = ~*__first.__seg_;
2363e519524SHoward Hinnant        if (__b)
237f3b851f0SMarshall Clow            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
2383e519524SHoward Hinnant    }
2393e519524SHoward Hinnant    // do last partial word
2403e519524SHoward Hinnant    if (__n > 0)
2413e519524SHoward Hinnant    {
2423e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
243423a8d77SHoward Hinnant        __storage_type __b = ~*__first.__seg_ & __m;
2443e519524SHoward Hinnant        if (__b)
245f3b851f0SMarshall Clow            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
2463e519524SHoward Hinnant    }
2473e519524SHoward Hinnant    return _It(__first.__seg_, static_cast<unsigned>(__n));
2483e519524SHoward Hinnant}
2493e519524SHoward Hinnant
250423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst, class _Tp>
2513e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
252423a8d77SHoward Hinnant__bit_iterator<_Cp, _IsConst>
253423a8d77SHoward Hinnantfind(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
2543e519524SHoward Hinnant{
255e4383379SHoward Hinnant    if (static_cast<bool>(__value_))
256781c476cSArthur O'Dwyer        return _VSTD::__find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
257781c476cSArthur O'Dwyer    return _VSTD::__find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
2583e519524SHoward Hinnant}
2593e519524SHoward Hinnant
2603e519524SHoward Hinnant// count
2613e519524SHoward Hinnant
262423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst>
263423a8d77SHoward Hinnanttypename __bit_iterator<_Cp, _IsConst>::difference_type
264423a8d77SHoward Hinnant__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
2653e519524SHoward Hinnant{
266423a8d77SHoward Hinnant    typedef __bit_iterator<_Cp, _IsConst> _It;
2673e519524SHoward Hinnant    typedef typename _It::__storage_type __storage_type;
2683e519524SHoward Hinnant    typedef typename _It::difference_type difference_type;
269aec08784SEric Fiselier    const int __bits_per_word = _It::__bits_per_word;
2703e519524SHoward Hinnant    difference_type __r = 0;
2713e519524SHoward Hinnant    // do first partial word
2723e519524SHoward Hinnant    if (__first.__ctz_ != 0)
2733e519524SHoward Hinnant    {
2743e519524SHoward Hinnant        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
275ce48a113SHoward Hinnant        __storage_type __dn = _VSTD::min(__clz_f, __n);
2763e519524SHoward Hinnant        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
277f3b851f0SMarshall Clow        __r = _VSTD::__libcpp_popcount(*__first.__seg_ & __m);
2783e519524SHoward Hinnant        __n -= __dn;
2793e519524SHoward Hinnant        ++__first.__seg_;
2803e519524SHoward Hinnant    }
2813e519524SHoward Hinnant    // do middle whole words
2823e519524SHoward Hinnant    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
283f3b851f0SMarshall Clow        __r += _VSTD::__libcpp_popcount(*__first.__seg_);
2843e519524SHoward Hinnant    // do last partial word
2853e519524SHoward Hinnant    if (__n > 0)
2863e519524SHoward Hinnant    {
2873e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
288f3b851f0SMarshall Clow        __r += _VSTD::__libcpp_popcount(*__first.__seg_ & __m);
2893e519524SHoward Hinnant    }
2903e519524SHoward Hinnant    return __r;
2913e519524SHoward Hinnant}
2923e519524SHoward Hinnant
293423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst>
294423a8d77SHoward Hinnanttypename __bit_iterator<_Cp, _IsConst>::difference_type
295423a8d77SHoward Hinnant__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
2963e519524SHoward Hinnant{
297423a8d77SHoward Hinnant    typedef __bit_iterator<_Cp, _IsConst> _It;
2983e519524SHoward Hinnant    typedef typename _It::__storage_type __storage_type;
2993e519524SHoward Hinnant    typedef typename _It::difference_type difference_type;
300aec08784SEric Fiselier    const int __bits_per_word = _It::__bits_per_word;
3013e519524SHoward Hinnant    difference_type __r = 0;
3023e519524SHoward Hinnant    // do first partial word
3033e519524SHoward Hinnant    if (__first.__ctz_ != 0)
3043e519524SHoward Hinnant    {
3053e519524SHoward Hinnant        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
306ce48a113SHoward Hinnant        __storage_type __dn = _VSTD::min(__clz_f, __n);
3073e519524SHoward Hinnant        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
308f3b851f0SMarshall Clow        __r = _VSTD::__libcpp_popcount(~*__first.__seg_ & __m);
3093e519524SHoward Hinnant        __n -= __dn;
3103e519524SHoward Hinnant        ++__first.__seg_;
3113e519524SHoward Hinnant    }
3123e519524SHoward Hinnant    // do middle whole words
3133e519524SHoward Hinnant    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
314f3b851f0SMarshall Clow        __r += _VSTD::__libcpp_popcount(~*__first.__seg_);
3153e519524SHoward Hinnant    // do last partial word
3163e519524SHoward Hinnant    if (__n > 0)
3173e519524SHoward Hinnant    {
3183e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
319f3b851f0SMarshall Clow        __r += _VSTD::__libcpp_popcount(~*__first.__seg_ & __m);
3203e519524SHoward Hinnant    }
3213e519524SHoward Hinnant    return __r;
3223e519524SHoward Hinnant}
3233e519524SHoward Hinnant
324423a8d77SHoward Hinnanttemplate <class _Cp, bool _IsConst, class _Tp>
3253e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
326423a8d77SHoward Hinnanttypename __bit_iterator<_Cp, _IsConst>::difference_type
327423a8d77SHoward Hinnantcount(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
3283e519524SHoward Hinnant{
329e4383379SHoward Hinnant    if (static_cast<bool>(__value_))
330781c476cSArthur O'Dwyer        return _VSTD::__count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
331781c476cSArthur O'Dwyer    return _VSTD::__count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
3323e519524SHoward Hinnant}
3333e519524SHoward Hinnant
3343e519524SHoward Hinnant// fill_n
3353e519524SHoward Hinnant
336c003db1fSHoward Hinnanttemplate <class _Cp>
3373e519524SHoward Hinnantvoid
338c003db1fSHoward Hinnant__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
3393e519524SHoward Hinnant{
340c003db1fSHoward Hinnant    typedef __bit_iterator<_Cp, false> _It;
3413e519524SHoward Hinnant    typedef typename _It::__storage_type __storage_type;
342aec08784SEric Fiselier    const int __bits_per_word = _It::__bits_per_word;
3433e519524SHoward Hinnant    // do first partial word
3443e519524SHoward Hinnant    if (__first.__ctz_ != 0)
3453e519524SHoward Hinnant    {
3463e519524SHoward Hinnant        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
347ce48a113SHoward Hinnant        __storage_type __dn = _VSTD::min(__clz_f, __n);
3483e519524SHoward Hinnant        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
3493e519524SHoward Hinnant        *__first.__seg_ &= ~__m;
3503e519524SHoward Hinnant        __n -= __dn;
3513e519524SHoward Hinnant        ++__first.__seg_;
3523e519524SHoward Hinnant    }
3533e519524SHoward Hinnant    // do middle whole words
3543e519524SHoward Hinnant    __storage_type __nw = __n / __bits_per_word;
3550068c591SEric Fiselier    _VSTD::memset(_VSTD::__to_address(__first.__seg_), 0, __nw * sizeof(__storage_type));
3563e519524SHoward Hinnant    __n -= __nw * __bits_per_word;
3573e519524SHoward Hinnant    // do last partial word
3583e519524SHoward Hinnant    if (__n > 0)
3593e519524SHoward Hinnant    {
3603e519524SHoward Hinnant        __first.__seg_ += __nw;
3613e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
3623e519524SHoward Hinnant        *__first.__seg_ &= ~__m;
3633e519524SHoward Hinnant    }
3643e519524SHoward Hinnant}
3653e519524SHoward Hinnant
366c003db1fSHoward Hinnanttemplate <class _Cp>
3673e519524SHoward Hinnantvoid
368c003db1fSHoward Hinnant__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
3693e519524SHoward Hinnant{
370c003db1fSHoward Hinnant    typedef __bit_iterator<_Cp, false> _It;
3713e519524SHoward Hinnant    typedef typename _It::__storage_type __storage_type;
372aec08784SEric Fiselier    const int __bits_per_word = _It::__bits_per_word;
3733e519524SHoward Hinnant    // do first partial word
3743e519524SHoward Hinnant    if (__first.__ctz_ != 0)
3753e519524SHoward Hinnant    {
3763e519524SHoward Hinnant        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
377ce48a113SHoward Hinnant        __storage_type __dn = _VSTD::min(__clz_f, __n);
3783e519524SHoward Hinnant        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
3793e519524SHoward Hinnant        *__first.__seg_ |= __m;
3803e519524SHoward Hinnant        __n -= __dn;
3813e519524SHoward Hinnant        ++__first.__seg_;
3823e519524SHoward Hinnant    }
3833e519524SHoward Hinnant    // do middle whole words
3843e519524SHoward Hinnant    __storage_type __nw = __n / __bits_per_word;
3850068c591SEric Fiselier    _VSTD::memset(_VSTD::__to_address(__first.__seg_), -1, __nw * sizeof(__storage_type));
3863e519524SHoward Hinnant    __n -= __nw * __bits_per_word;
3873e519524SHoward Hinnant    // do last partial word
3883e519524SHoward Hinnant    if (__n > 0)
3893e519524SHoward Hinnant    {
3903e519524SHoward Hinnant        __first.__seg_ += __nw;
3913e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
3923e519524SHoward Hinnant        *__first.__seg_ |= __m;
3933e519524SHoward Hinnant    }
3943e519524SHoward Hinnant}
3953e519524SHoward Hinnant
396c003db1fSHoward Hinnanttemplate <class _Cp>
3973af48ef7SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
3983e519524SHoward Hinnantvoid
399c003db1fSHoward Hinnantfill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)
4003e519524SHoward Hinnant{
4013e519524SHoward Hinnant    if (__n > 0)
4023e519524SHoward Hinnant    {
403e4383379SHoward Hinnant        if (__value_)
404781c476cSArthur O'Dwyer            _VSTD::__fill_n_true(__first, __n);
4053e519524SHoward Hinnant        else
406781c476cSArthur O'Dwyer            _VSTD::__fill_n_false(__first, __n);
4073e519524SHoward Hinnant    }
4083e519524SHoward Hinnant}
4093e519524SHoward Hinnant
4103e519524SHoward Hinnant// fill
4113e519524SHoward Hinnant
412c003db1fSHoward Hinnanttemplate <class _Cp>
4133e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4143e519524SHoward Hinnantvoid
415c003db1fSHoward Hinnantfill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_)
4163e519524SHoward Hinnant{
417c003db1fSHoward Hinnant    _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_);
4183e519524SHoward Hinnant}
4193e519524SHoward Hinnant
4203e519524SHoward Hinnant// copy
4213e519524SHoward Hinnant
422c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst>
423c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
424c003db1fSHoward Hinnant__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
425c003db1fSHoward Hinnant                                                     __bit_iterator<_Cp, false> __result)
4263e519524SHoward Hinnant{
427c003db1fSHoward Hinnant    typedef __bit_iterator<_Cp, _IsConst> _In;
4283e519524SHoward Hinnant    typedef  typename _In::difference_type difference_type;
4293e519524SHoward Hinnant    typedef typename _In::__storage_type __storage_type;
430aec08784SEric Fiselier    const int __bits_per_word = _In::__bits_per_word;
4313e519524SHoward Hinnant    difference_type __n = __last - __first;
4323e519524SHoward Hinnant    if (__n > 0)
4333e519524SHoward Hinnant    {
4343e519524SHoward Hinnant        // do first word
4353e519524SHoward Hinnant        if (__first.__ctz_ != 0)
4363e519524SHoward Hinnant        {
4373e519524SHoward Hinnant            unsigned __clz = __bits_per_word - __first.__ctz_;
438ce48a113SHoward Hinnant            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
4393e519524SHoward Hinnant            __n -= __dn;
4403e519524SHoward Hinnant            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
4413e519524SHoward Hinnant            __storage_type __b = *__first.__seg_ & __m;
4423e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
4433e519524SHoward Hinnant            *__result.__seg_ |= __b;
4443e519524SHoward Hinnant            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
4453e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
4463e519524SHoward Hinnant            ++__first.__seg_;
4473e519524SHoward Hinnant            // __first.__ctz_ = 0;
4483e519524SHoward Hinnant        }
4493e519524SHoward Hinnant        // __first.__ctz_ == 0;
4503e519524SHoward Hinnant        // do middle words
4513e519524SHoward Hinnant        __storage_type __nw = __n / __bits_per_word;
4520068c591SEric Fiselier        _VSTD::memmove(_VSTD::__to_address(__result.__seg_),
4530068c591SEric Fiselier                       _VSTD::__to_address(__first.__seg_),
4543ec1f00bSHoward Hinnant                       __nw * sizeof(__storage_type));
4553e519524SHoward Hinnant        __n -= __nw * __bits_per_word;
4563e519524SHoward Hinnant        __result.__seg_ += __nw;
4573e519524SHoward Hinnant        // do last word
4583e519524SHoward Hinnant        if (__n > 0)
4593e519524SHoward Hinnant        {
4603e519524SHoward Hinnant            __first.__seg_ += __nw;
4613e519524SHoward Hinnant            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
4623e519524SHoward Hinnant            __storage_type __b = *__first.__seg_ & __m;
4633e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
4643e519524SHoward Hinnant            *__result.__seg_ |= __b;
4653e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>(__n);
4663e519524SHoward Hinnant        }
4673e519524SHoward Hinnant    }
4683e519524SHoward Hinnant    return __result;
4693e519524SHoward Hinnant}
4703e519524SHoward Hinnant
471c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst>
472c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
473c003db1fSHoward Hinnant__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
474c003db1fSHoward Hinnant                                                       __bit_iterator<_Cp, false> __result)
4753e519524SHoward Hinnant{
476c003db1fSHoward Hinnant    typedef __bit_iterator<_Cp, _IsConst> _In;
4773e519524SHoward Hinnant    typedef  typename _In::difference_type difference_type;
4783e519524SHoward Hinnant    typedef typename _In::__storage_type __storage_type;
479aec08784SEric Fiselier    static const int __bits_per_word = _In::__bits_per_word;
4803e519524SHoward Hinnant    difference_type __n = __last - __first;
4813e519524SHoward Hinnant    if (__n > 0)
4823e519524SHoward Hinnant    {
4833e519524SHoward Hinnant        // do first word
4843e519524SHoward Hinnant        if (__first.__ctz_ != 0)
4853e519524SHoward Hinnant        {
4863e519524SHoward Hinnant            unsigned __clz_f = __bits_per_word - __first.__ctz_;
487ce48a113SHoward Hinnant            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
4883e519524SHoward Hinnant            __n -= __dn;
4893e519524SHoward Hinnant            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
4903e519524SHoward Hinnant            __storage_type __b = *__first.__seg_ & __m;
4913e519524SHoward Hinnant            unsigned __clz_r = __bits_per_word - __result.__ctz_;
492ce48a113SHoward Hinnant            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
4933e519524SHoward Hinnant            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
4943e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
4953e519524SHoward Hinnant            if (__result.__ctz_ > __first.__ctz_)
4963e519524SHoward Hinnant                *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
4973e519524SHoward Hinnant            else
4983e519524SHoward Hinnant                *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
4993e519524SHoward Hinnant            __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
5003e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_)  % __bits_per_word);
5013e519524SHoward Hinnant            __dn -= __ddn;
5023e519524SHoward Hinnant            if (__dn > 0)
5033e519524SHoward Hinnant            {
5043e519524SHoward Hinnant                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
5053e519524SHoward Hinnant                *__result.__seg_ &= ~__m;
5063e519524SHoward Hinnant                *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
5073e519524SHoward Hinnant                __result.__ctz_ = static_cast<unsigned>(__dn);
5083e519524SHoward Hinnant            }
5093e519524SHoward Hinnant            ++__first.__seg_;
5103e519524SHoward Hinnant            // __first.__ctz_ = 0;
5113e519524SHoward Hinnant        }
5123e519524SHoward Hinnant        // __first.__ctz_ == 0;
5133e519524SHoward Hinnant        // do middle words
5143e519524SHoward Hinnant        unsigned __clz_r = __bits_per_word - __result.__ctz_;
5153e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) << __result.__ctz_;
5163e519524SHoward Hinnant        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
5173e519524SHoward Hinnant        {
5183e519524SHoward Hinnant            __storage_type __b = *__first.__seg_;
5193e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
5203e519524SHoward Hinnant            *__result.__seg_ |= __b << __result.__ctz_;
5213e519524SHoward Hinnant            ++__result.__seg_;
5223e519524SHoward Hinnant            *__result.__seg_ &= __m;
5233e519524SHoward Hinnant            *__result.__seg_ |= __b >> __clz_r;
5243e519524SHoward Hinnant        }
5253e519524SHoward Hinnant        // do last word
5263e519524SHoward Hinnant        if (__n > 0)
5273e519524SHoward Hinnant        {
5283e519524SHoward Hinnant            __m = ~__storage_type(0) >> (__bits_per_word - __n);
5293e519524SHoward Hinnant            __storage_type __b = *__first.__seg_ & __m;
530ce48a113SHoward Hinnant            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
5313e519524SHoward Hinnant            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
5323e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
5333e519524SHoward Hinnant            *__result.__seg_ |= __b << __result.__ctz_;
5343e519524SHoward Hinnant            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
5353e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
5363e519524SHoward Hinnant            __n -= __dn;
5373e519524SHoward Hinnant            if (__n > 0)
5383e519524SHoward Hinnant            {
5393e519524SHoward Hinnant                __m = ~__storage_type(0) >> (__bits_per_word - __n);
5403e519524SHoward Hinnant                *__result.__seg_ &= ~__m;
5413e519524SHoward Hinnant                *__result.__seg_ |= __b >> __dn;
5423e519524SHoward Hinnant                __result.__ctz_ = static_cast<unsigned>(__n);
5433e519524SHoward Hinnant            }
5443e519524SHoward Hinnant        }
5453e519524SHoward Hinnant    }
5463e519524SHoward Hinnant    return __result;
5473e519524SHoward Hinnant}
5483e519524SHoward Hinnant
549c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst>
5503e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
551c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
552c003db1fSHoward Hinnantcopy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
5533e519524SHoward Hinnant{
5543e519524SHoward Hinnant    if (__first.__ctz_ == __result.__ctz_)
555781c476cSArthur O'Dwyer        return _VSTD::__copy_aligned(__first, __last, __result);
556781c476cSArthur O'Dwyer    return _VSTD::__copy_unaligned(__first, __last, __result);
5573e519524SHoward Hinnant}
5583e519524SHoward Hinnant
5593e519524SHoward Hinnant// copy_backward
5603e519524SHoward Hinnant
561c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst>
562c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
563c003db1fSHoward Hinnant__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
564c003db1fSHoward Hinnant                                                     __bit_iterator<_Cp, false> __result)
5653e519524SHoward Hinnant{
566c003db1fSHoward Hinnant    typedef __bit_iterator<_Cp, _IsConst> _In;
5673e519524SHoward Hinnant    typedef  typename _In::difference_type difference_type;
5683e519524SHoward Hinnant    typedef typename _In::__storage_type __storage_type;
569aec08784SEric Fiselier    const int __bits_per_word = _In::__bits_per_word;
5703e519524SHoward Hinnant    difference_type __n = __last - __first;
5713e519524SHoward Hinnant    if (__n > 0)
5723e519524SHoward Hinnant    {
5733e519524SHoward Hinnant        // do first word
5743e519524SHoward Hinnant        if (__last.__ctz_ != 0)
5753e519524SHoward Hinnant        {
576ce48a113SHoward Hinnant            difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
5773e519524SHoward Hinnant            __n -= __dn;
5783e519524SHoward Hinnant            unsigned __clz = __bits_per_word - __last.__ctz_;
5793e519524SHoward Hinnant            __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
5803e519524SHoward Hinnant            __storage_type __b = *__last.__seg_ & __m;
5813e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
5823e519524SHoward Hinnant            *__result.__seg_ |= __b;
5833e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
5843e519524SHoward Hinnant                                                       __result.__ctz_)  % __bits_per_word);
5853e519524SHoward Hinnant            // __last.__ctz_ = 0
5863e519524SHoward Hinnant         }
5873e519524SHoward Hinnant        // __last.__ctz_ == 0 || __n == 0
5883e519524SHoward Hinnant        // __result.__ctz_ == 0 || __n == 0
5893e519524SHoward Hinnant        // do middle words
5903e519524SHoward Hinnant        __storage_type __nw = __n / __bits_per_word;
5913e519524SHoward Hinnant        __result.__seg_ -= __nw;
5923e519524SHoward Hinnant        __last.__seg_ -= __nw;
5930068c591SEric Fiselier        _VSTD::memmove(_VSTD::__to_address(__result.__seg_),
5940068c591SEric Fiselier                       _VSTD::__to_address(__last.__seg_),
5953ec1f00bSHoward Hinnant                       __nw * sizeof(__storage_type));
5963e519524SHoward Hinnant        __n -= __nw * __bits_per_word;
5973e519524SHoward Hinnant        // do last word
5983e519524SHoward Hinnant        if (__n > 0)
5993e519524SHoward Hinnant        {
6003e519524SHoward Hinnant            __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
6013e519524SHoward Hinnant            __storage_type __b = *--__last.__seg_ & __m;
6023e519524SHoward Hinnant            *--__result.__seg_ &= ~__m;
6033e519524SHoward Hinnant            *__result.__seg_ |= __b;
6043e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
6053e519524SHoward Hinnant        }
6063e519524SHoward Hinnant    }
6073e519524SHoward Hinnant    return __result;
6083e519524SHoward Hinnant}
6093e519524SHoward Hinnant
610c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst>
611c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
612c003db1fSHoward Hinnant__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
613c003db1fSHoward Hinnant                                                       __bit_iterator<_Cp, false> __result)
6143e519524SHoward Hinnant{
615c003db1fSHoward Hinnant    typedef __bit_iterator<_Cp, _IsConst> _In;
6163e519524SHoward Hinnant    typedef  typename _In::difference_type difference_type;
6173e519524SHoward Hinnant    typedef typename _In::__storage_type __storage_type;
618aec08784SEric Fiselier    const int __bits_per_word = _In::__bits_per_word;
6193e519524SHoward Hinnant    difference_type __n = __last - __first;
6203e519524SHoward Hinnant    if (__n > 0)
6213e519524SHoward Hinnant    {
6223e519524SHoward Hinnant        // do first word
6233e519524SHoward Hinnant        if (__last.__ctz_ != 0)
6243e519524SHoward Hinnant        {
625ce48a113SHoward Hinnant            difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
6263e519524SHoward Hinnant            __n -= __dn;
6273e519524SHoward Hinnant            unsigned __clz_l = __bits_per_word - __last.__ctz_;
6283e519524SHoward Hinnant            __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
6293e519524SHoward Hinnant            __storage_type __b = *__last.__seg_ & __m;
6303e519524SHoward Hinnant            unsigned __clz_r = __bits_per_word - __result.__ctz_;
631ce48a113SHoward Hinnant            __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_));
6323e519524SHoward Hinnant            if (__ddn > 0)
6333e519524SHoward Hinnant            {
6343e519524SHoward Hinnant                __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
6353e519524SHoward Hinnant                *__result.__seg_ &= ~__m;
6363e519524SHoward Hinnant                if (__result.__ctz_ > __last.__ctz_)
6373e519524SHoward Hinnant                    *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
6383e519524SHoward Hinnant                else
6393e519524SHoward Hinnant                    *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
6403e519524SHoward Hinnant                __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) +
6413e519524SHoward Hinnant                                                         __result.__ctz_)  % __bits_per_word);
6423e519524SHoward Hinnant                __dn -= __ddn;
6433e519524SHoward Hinnant            }
6443e519524SHoward Hinnant            if (__dn > 0)
6453e519524SHoward Hinnant            {
6463e519524SHoward Hinnant                // __result.__ctz_ == 0
6473e519524SHoward Hinnant                --__result.__seg_;
6483e519524SHoward Hinnant                __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
6493e519524SHoward Hinnant                __m = ~__storage_type(0) << __result.__ctz_;
6503e519524SHoward Hinnant                *__result.__seg_ &= ~__m;
6513e519524SHoward Hinnant                __last.__ctz_ -= __dn + __ddn;
6523e519524SHoward Hinnant                *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
6533e519524SHoward Hinnant            }
6543e519524SHoward Hinnant            // __last.__ctz_ = 0
6553e519524SHoward Hinnant         }
6563e519524SHoward Hinnant        // __last.__ctz_ == 0 || __n == 0
6573e519524SHoward Hinnant        // __result.__ctz_ != 0 || __n == 0
6583e519524SHoward Hinnant        // do middle words
6593e519524SHoward Hinnant        unsigned __clz_r = __bits_per_word - __result.__ctz_;
6603e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) >> __clz_r;
6613e519524SHoward Hinnant        for (; __n >= __bits_per_word; __n -= __bits_per_word)
6623e519524SHoward Hinnant        {
6633e519524SHoward Hinnant            __storage_type __b = *--__last.__seg_;
6643e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
6653e519524SHoward Hinnant            *__result.__seg_ |= __b >> __clz_r;
6663e519524SHoward Hinnant            *--__result.__seg_ &= __m;
6673e519524SHoward Hinnant            *__result.__seg_ |= __b << __result.__ctz_;
6683e519524SHoward Hinnant        }
6693e519524SHoward Hinnant        // do last word
6703e519524SHoward Hinnant        if (__n > 0)
6713e519524SHoward Hinnant        {
6723e519524SHoward Hinnant            __m = ~__storage_type(0) << (__bits_per_word - __n);
6733e519524SHoward Hinnant            __storage_type __b = *--__last.__seg_ & __m;
674c206366fSHoward Hinnant            __clz_r = __bits_per_word - __result.__ctz_;
675ce48a113SHoward Hinnant            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_));
6763e519524SHoward Hinnant            __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
6773e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
6783e519524SHoward Hinnant            *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
6793e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
6803e519524SHoward Hinnant                                                     __result.__ctz_)  % __bits_per_word);
6813e519524SHoward Hinnant            __n -= __dn;
6823e519524SHoward Hinnant            if (__n > 0)
6833e519524SHoward Hinnant            {
6843e519524SHoward Hinnant                // __result.__ctz_ == 0
6853e519524SHoward Hinnant                --__result.__seg_;
6863e519524SHoward Hinnant                __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
6873e519524SHoward Hinnant                __m = ~__storage_type(0) << __result.__ctz_;
6883e519524SHoward Hinnant                *__result.__seg_ &= ~__m;
6893e519524SHoward Hinnant                *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
6903e519524SHoward Hinnant            }
6913e519524SHoward Hinnant        }
6923e519524SHoward Hinnant    }
6933e519524SHoward Hinnant    return __result;
6943e519524SHoward Hinnant}
6953e519524SHoward Hinnant
696c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst>
6973e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
698c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
699c003db1fSHoward Hinnantcopy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
7003e519524SHoward Hinnant{
7013e519524SHoward Hinnant    if (__last.__ctz_ == __result.__ctz_)
702781c476cSArthur O'Dwyer        return _VSTD::__copy_backward_aligned(__first, __last, __result);
703781c476cSArthur O'Dwyer    return _VSTD::__copy_backward_unaligned(__first, __last, __result);
7043e519524SHoward Hinnant}
7053e519524SHoward Hinnant
7063e519524SHoward Hinnant// move
7073e519524SHoward Hinnant
708c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst>
7093e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
710c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
711c003db1fSHoward Hinnantmove(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
7123e519524SHoward Hinnant{
713ce48a113SHoward Hinnant    return _VSTD::copy(__first, __last, __result);
7143e519524SHoward Hinnant}
7153e519524SHoward Hinnant
7163e519524SHoward Hinnant// move_backward
7173e519524SHoward Hinnant
718c003db1fSHoward Hinnanttemplate <class _Cp, bool _IsConst>
7193e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
720c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
721c003db1fSHoward Hinnantmove_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
7223e519524SHoward Hinnant{
72308de4b0dSMarshall Clow    return _VSTD::copy_backward(__first, __last, __result);
7243e519524SHoward Hinnant}
7253e519524SHoward Hinnant
7263e519524SHoward Hinnant// swap_ranges
7273e519524SHoward Hinnant
728dbe81119SHoward Hinnanttemplate <class __C1, class __C2>
729dbe81119SHoward Hinnant__bit_iterator<__C2, false>
730dbe81119SHoward Hinnant__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
731dbe81119SHoward Hinnant                      __bit_iterator<__C2, false> __result)
7323e519524SHoward Hinnant{
733dbe81119SHoward Hinnant    typedef __bit_iterator<__C1, false> _I1;
7343e519524SHoward Hinnant    typedef  typename _I1::difference_type difference_type;
7353e519524SHoward Hinnant    typedef typename _I1::__storage_type __storage_type;
736aec08784SEric Fiselier    const int __bits_per_word = _I1::__bits_per_word;
7373e519524SHoward Hinnant    difference_type __n = __last - __first;
7383e519524SHoward Hinnant    if (__n > 0)
7393e519524SHoward Hinnant    {
7403e519524SHoward Hinnant        // do first word
7413e519524SHoward Hinnant        if (__first.__ctz_ != 0)
7423e519524SHoward Hinnant        {
7433e519524SHoward Hinnant            unsigned __clz = __bits_per_word - __first.__ctz_;
744ce48a113SHoward Hinnant            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
7453e519524SHoward Hinnant            __n -= __dn;
7463e519524SHoward Hinnant            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
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.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
7543e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
7553e519524SHoward Hinnant            ++__first.__seg_;
7563e519524SHoward Hinnant            // __first.__ctz_ = 0;
7573e519524SHoward Hinnant        }
7583e519524SHoward Hinnant        // __first.__ctz_ == 0;
7593e519524SHoward Hinnant        // do middle words
7603e519524SHoward Hinnant        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
7613e519524SHoward Hinnant            swap(*__first.__seg_, *__result.__seg_);
7623e519524SHoward Hinnant        // do last word
7633e519524SHoward Hinnant        if (__n > 0)
7643e519524SHoward Hinnant        {
7653e519524SHoward Hinnant            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
7663e519524SHoward Hinnant            __storage_type __b1 = *__first.__seg_ & __m;
7673e519524SHoward Hinnant            *__first.__seg_ &= ~__m;
7683e519524SHoward Hinnant            __storage_type __b2 = *__result.__seg_ & __m;
7693e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
7703e519524SHoward Hinnant            *__result.__seg_ |= __b1;
7713e519524SHoward Hinnant            *__first.__seg_  |= __b2;
7723e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>(__n);
7733e519524SHoward Hinnant        }
7743e519524SHoward Hinnant    }
7753e519524SHoward Hinnant    return __result;
7763e519524SHoward Hinnant}
7773e519524SHoward Hinnant
778dbe81119SHoward Hinnanttemplate <class __C1, class __C2>
779dbe81119SHoward Hinnant__bit_iterator<__C2, false>
780dbe81119SHoward Hinnant__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
781dbe81119SHoward Hinnant                        __bit_iterator<__C2, false> __result)
7823e519524SHoward Hinnant{
783dbe81119SHoward Hinnant    typedef __bit_iterator<__C1, false> _I1;
7843e519524SHoward Hinnant    typedef  typename _I1::difference_type difference_type;
7853e519524SHoward Hinnant    typedef typename _I1::__storage_type __storage_type;
786aec08784SEric Fiselier    const int __bits_per_word = _I1::__bits_per_word;
7873e519524SHoward Hinnant    difference_type __n = __last - __first;
7883e519524SHoward Hinnant    if (__n > 0)
7893e519524SHoward Hinnant    {
7903e519524SHoward Hinnant        // do first word
7913e519524SHoward Hinnant        if (__first.__ctz_ != 0)
7923e519524SHoward Hinnant        {
7933e519524SHoward Hinnant            unsigned __clz_f = __bits_per_word - __first.__ctz_;
794ce48a113SHoward Hinnant            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
7953e519524SHoward Hinnant            __n -= __dn;
7963e519524SHoward Hinnant            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
7973e519524SHoward Hinnant            __storage_type __b1 = *__first.__seg_ & __m;
7983e519524SHoward Hinnant            *__first.__seg_ &= ~__m;
7993e519524SHoward Hinnant            unsigned __clz_r = __bits_per_word - __result.__ctz_;
800ce48a113SHoward Hinnant            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
8013e519524SHoward Hinnant            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
8023e519524SHoward Hinnant            __storage_type __b2 = *__result.__seg_ & __m;
8033e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
8043e519524SHoward Hinnant            if (__result.__ctz_ > __first.__ctz_)
8053e519524SHoward Hinnant            {
8063e519524SHoward Hinnant                unsigned __s = __result.__ctz_ - __first.__ctz_;
8073e519524SHoward Hinnant                *__result.__seg_ |= __b1 << __s;
8083e519524SHoward Hinnant                *__first.__seg_  |= __b2 >> __s;
8093e519524SHoward Hinnant            }
8103e519524SHoward Hinnant            else
8113e519524SHoward Hinnant            {
8123e519524SHoward Hinnant                unsigned __s = __first.__ctz_ - __result.__ctz_;
8133e519524SHoward Hinnant                *__result.__seg_ |= __b1 >> __s;
8143e519524SHoward Hinnant                *__first.__seg_  |= __b2 << __s;
8153e519524SHoward Hinnant            }
8163e519524SHoward Hinnant            __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
8173e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_)  % __bits_per_word);
8183e519524SHoward Hinnant            __dn -= __ddn;
8193e519524SHoward Hinnant            if (__dn > 0)
8203e519524SHoward Hinnant            {
8213e519524SHoward Hinnant                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
8223e519524SHoward Hinnant                __b2 = *__result.__seg_ & __m;
8233e519524SHoward Hinnant                *__result.__seg_ &= ~__m;
8243e519524SHoward Hinnant                unsigned __s = __first.__ctz_ + __ddn;
8253e519524SHoward Hinnant                *__result.__seg_ |= __b1 >> __s;
8263e519524SHoward Hinnant                *__first.__seg_  |= __b2 << __s;
8273e519524SHoward Hinnant                __result.__ctz_ = static_cast<unsigned>(__dn);
8283e519524SHoward Hinnant            }
8293e519524SHoward Hinnant            ++__first.__seg_;
8303e519524SHoward Hinnant            // __first.__ctz_ = 0;
8313e519524SHoward Hinnant        }
8323e519524SHoward Hinnant        // __first.__ctz_ == 0;
8333e519524SHoward Hinnant        // do middle words
8343e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) << __result.__ctz_;
8353e519524SHoward Hinnant        unsigned __clz_r = __bits_per_word - __result.__ctz_;
8363e519524SHoward Hinnant        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
8373e519524SHoward Hinnant        {
8383e519524SHoward Hinnant            __storage_type __b1 = *__first.__seg_;
8393e519524SHoward Hinnant            __storage_type __b2 = *__result.__seg_ & __m;
8403e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
8413e519524SHoward Hinnant            *__result.__seg_ |= __b1 << __result.__ctz_;
8423e519524SHoward Hinnant            *__first.__seg_  = __b2 >> __result.__ctz_;
8433e519524SHoward Hinnant            ++__result.__seg_;
8443e519524SHoward Hinnant            __b2 = *__result.__seg_ & ~__m;
8453e519524SHoward Hinnant            *__result.__seg_ &= __m;
8463e519524SHoward Hinnant            *__result.__seg_ |= __b1 >> __clz_r;
8473e519524SHoward Hinnant            *__first.__seg_  |= __b2 << __clz_r;
8483e519524SHoward Hinnant        }
8493e519524SHoward Hinnant        // do last word
8503e519524SHoward Hinnant        if (__n > 0)
8513e519524SHoward Hinnant        {
8523e519524SHoward Hinnant            __m = ~__storage_type(0) >> (__bits_per_word - __n);
8533e519524SHoward Hinnant            __storage_type __b1 = *__first.__seg_ & __m;
8543e519524SHoward Hinnant            *__first.__seg_ &= ~__m;
855ce48a113SHoward Hinnant            __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r);
8563e519524SHoward Hinnant            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
8573e519524SHoward Hinnant            __storage_type __b2 = *__result.__seg_ & __m;
8583e519524SHoward Hinnant            *__result.__seg_ &= ~__m;
8593e519524SHoward Hinnant            *__result.__seg_ |= __b1 << __result.__ctz_;
8603e519524SHoward Hinnant            *__first.__seg_  |= __b2 >> __result.__ctz_;
8613e519524SHoward Hinnant            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
8623e519524SHoward Hinnant            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
8633e519524SHoward Hinnant            __n -= __dn;
8643e519524SHoward Hinnant            if (__n > 0)
8653e519524SHoward Hinnant            {
8663e519524SHoward Hinnant                __m = ~__storage_type(0) >> (__bits_per_word - __n);
8673e519524SHoward Hinnant                __b2 = *__result.__seg_ & __m;
8683e519524SHoward Hinnant                *__result.__seg_ &= ~__m;
8693e519524SHoward Hinnant                *__result.__seg_ |= __b1 >> __dn;
8703e519524SHoward Hinnant                *__first.__seg_  |= __b2 << __dn;
8713e519524SHoward Hinnant                __result.__ctz_ = static_cast<unsigned>(__n);
8723e519524SHoward Hinnant            }
8733e519524SHoward Hinnant        }
8743e519524SHoward Hinnant    }
8753e519524SHoward Hinnant    return __result;
8763e519524SHoward Hinnant}
8773e519524SHoward Hinnant
878dbe81119SHoward Hinnanttemplate <class __C1, class __C2>
8793e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
880dbe81119SHoward Hinnant__bit_iterator<__C2, false>
881dbe81119SHoward Hinnantswap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
882dbe81119SHoward Hinnant            __bit_iterator<__C2, false> __first2)
8833e519524SHoward Hinnant{
8843e519524SHoward Hinnant    if (__first1.__ctz_ == __first2.__ctz_)
885781c476cSArthur O'Dwyer        return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2);
886781c476cSArthur O'Dwyer    return _VSTD::__swap_ranges_unaligned(__first1, __last1, __first2);
8873e519524SHoward Hinnant}
8883e519524SHoward Hinnant
8893e519524SHoward Hinnant// rotate
8903e519524SHoward Hinnant
891c003db1fSHoward Hinnanttemplate <class _Cp>
8923e519524SHoward Hinnantstruct __bit_array
8933e519524SHoward Hinnant{
894c003db1fSHoward Hinnant    typedef typename _Cp::difference_type difference_type;
895c003db1fSHoward Hinnant    typedef typename _Cp::__storage_type  __storage_type;
8963ec1f00bSHoward Hinnant    typedef typename _Cp::__storage_pointer __storage_pointer;
897c003db1fSHoward Hinnant    typedef typename _Cp::iterator        iterator;
898c003db1fSHoward Hinnant    static const unsigned __bits_per_word = _Cp::__bits_per_word;
899c003db1fSHoward Hinnant    static const unsigned _Np = 4;
9003e519524SHoward Hinnant
9013e519524SHoward Hinnant    difference_type __size_;
902c003db1fSHoward Hinnant    __storage_type __word_[_Np];
9033e519524SHoward Hinnant
9043e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY static difference_type capacity()
905c003db1fSHoward Hinnant        {return static_cast<difference_type>(_Np * __bits_per_word);}
9063e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
9073ec1f00bSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY iterator begin()
9083ec1f00bSHoward Hinnant    {
9093ec1f00bSHoward Hinnant        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
9103ec1f00bSHoward Hinnant    }
9113ec1f00bSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY iterator end()
9123ec1f00bSHoward Hinnant    {
9133ec1f00bSHoward Hinnant        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
9143ec1f00bSHoward Hinnant                                                  static_cast<unsigned>(__size_ % __bits_per_word));
9153ec1f00bSHoward Hinnant    }
9163e519524SHoward Hinnant};
9173e519524SHoward Hinnant
918c003db1fSHoward Hinnanttemplate <class _Cp>
919c003db1fSHoward Hinnant__bit_iterator<_Cp, false>
920c003db1fSHoward Hinnantrotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)
9213e519524SHoward Hinnant{
922c003db1fSHoward Hinnant    typedef __bit_iterator<_Cp, false> _I1;
9233e519524SHoward Hinnant    typedef  typename _I1::difference_type difference_type;
9243e519524SHoward Hinnant    difference_type __d1 = __middle - __first;
9253e519524SHoward Hinnant    difference_type __d2 = __last - __middle;
9263e519524SHoward Hinnant    _I1 __r = __first + __d2;
9273e519524SHoward Hinnant    while (__d1 != 0 && __d2 != 0)
9283e519524SHoward Hinnant    {
9293e519524SHoward Hinnant        if (__d1 <= __d2)
9303e519524SHoward Hinnant        {
931c003db1fSHoward Hinnant            if (__d1 <= __bit_array<_Cp>::capacity())
9323e519524SHoward Hinnant            {
933c003db1fSHoward Hinnant                __bit_array<_Cp> __b(__d1);
934ce48a113SHoward Hinnant                _VSTD::copy(__first, __middle, __b.begin());
935ce48a113SHoward Hinnant                _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first));
9363e519524SHoward Hinnant                break;
9373e519524SHoward Hinnant            }
9383e519524SHoward Hinnant            else
9393e519524SHoward Hinnant            {
940c003db1fSHoward Hinnant                __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle);
9413e519524SHoward Hinnant                __first = __middle;
9423e519524SHoward Hinnant                __middle = __mp;
9433e519524SHoward Hinnant                __d2 -= __d1;
9443e519524SHoward Hinnant            }
9453e519524SHoward Hinnant        }
9463e519524SHoward Hinnant        else
9473e519524SHoward Hinnant        {
948c003db1fSHoward Hinnant            if (__d2 <= __bit_array<_Cp>::capacity())
9493e519524SHoward Hinnant            {
950c003db1fSHoward Hinnant                __bit_array<_Cp> __b(__d2);
951ce48a113SHoward Hinnant                _VSTD::copy(__middle, __last, __b.begin());
952ce48a113SHoward Hinnant                _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last));
9533e519524SHoward Hinnant                break;
9543e519524SHoward Hinnant            }
9553e519524SHoward Hinnant            else
9563e519524SHoward Hinnant            {
957c003db1fSHoward Hinnant                __bit_iterator<_Cp, false> __mp = __first + __d2;
958ce48a113SHoward Hinnant                _VSTD::swap_ranges(__first, __mp, __middle);
9593e519524SHoward Hinnant                __first = __mp;
9603e519524SHoward Hinnant                __d1 -= __d2;
9613e519524SHoward Hinnant            }
9623e519524SHoward Hinnant        }
9633e519524SHoward Hinnant    }
9643e519524SHoward Hinnant    return __r;
9653e519524SHoward Hinnant}
9663e519524SHoward Hinnant
9673e519524SHoward Hinnant// equal
9683e519524SHoward Hinnant
9691237dccaSHoward Hinnanttemplate <class _Cp, bool _IC1, bool _IC2>
9703e519524SHoward Hinnantbool
9711237dccaSHoward Hinnant__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
9721237dccaSHoward Hinnant                  __bit_iterator<_Cp, _IC2> __first2)
9733e519524SHoward Hinnant{
9741237dccaSHoward Hinnant    typedef __bit_iterator<_Cp, _IC1> _It;
9753e519524SHoward Hinnant    typedef  typename _It::difference_type difference_type;
9763e519524SHoward Hinnant    typedef typename _It::__storage_type __storage_type;
977aec08784SEric Fiselier    static const int __bits_per_word = _It::__bits_per_word;
9783e519524SHoward Hinnant    difference_type __n = __last1 - __first1;
9793e519524SHoward Hinnant    if (__n > 0)
9803e519524SHoward Hinnant    {
9813e519524SHoward Hinnant        // do first word
9823e519524SHoward Hinnant        if (__first1.__ctz_ != 0)
9833e519524SHoward Hinnant        {
9843e519524SHoward Hinnant            unsigned __clz_f = __bits_per_word - __first1.__ctz_;
985ce48a113SHoward Hinnant            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
9863e519524SHoward Hinnant            __n -= __dn;
9873e519524SHoward Hinnant            __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
9883e519524SHoward Hinnant            __storage_type __b = *__first1.__seg_ & __m;
9893e519524SHoward Hinnant            unsigned __clz_r = __bits_per_word - __first2.__ctz_;
990ce48a113SHoward Hinnant            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
9913e519524SHoward Hinnant            __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
9923e519524SHoward Hinnant            if (__first2.__ctz_ > __first1.__ctz_)
9934c0de496SHoward Hinnant            {
9943e519524SHoward Hinnant                if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
9953e519524SHoward Hinnant                    return false;
9964c0de496SHoward Hinnant            }
9973e519524SHoward Hinnant            else
9984c0de496SHoward Hinnant            {
9993e519524SHoward Hinnant                if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
10003e519524SHoward Hinnant                    return false;
10014c0de496SHoward Hinnant            }
10023e519524SHoward Hinnant            __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
10033e519524SHoward Hinnant            __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_)  % __bits_per_word);
10043e519524SHoward Hinnant            __dn -= __ddn;
10053e519524SHoward Hinnant            if (__dn > 0)
10063e519524SHoward Hinnant            {
10073e519524SHoward Hinnant                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
10083e519524SHoward Hinnant                if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
10093e519524SHoward Hinnant                    return false;
10103e519524SHoward Hinnant                __first2.__ctz_ = static_cast<unsigned>(__dn);
10113e519524SHoward Hinnant            }
10123e519524SHoward Hinnant            ++__first1.__seg_;
10133e519524SHoward Hinnant            // __first1.__ctz_ = 0;
10143e519524SHoward Hinnant        }
10153e519524SHoward Hinnant        // __first1.__ctz_ == 0;
10163e519524SHoward Hinnant        // do middle words
10173e519524SHoward Hinnant        unsigned __clz_r = __bits_per_word - __first2.__ctz_;
10183e519524SHoward Hinnant        __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
10193e519524SHoward Hinnant        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_)
10203e519524SHoward Hinnant        {
10213e519524SHoward Hinnant            __storage_type __b = *__first1.__seg_;
10223e519524SHoward Hinnant            if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
10233e519524SHoward Hinnant                return false;
10243e519524SHoward Hinnant            ++__first2.__seg_;
10253e519524SHoward Hinnant            if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
10263e519524SHoward Hinnant                return false;
10273e519524SHoward Hinnant        }
10283e519524SHoward Hinnant        // do last word
10293e519524SHoward Hinnant        if (__n > 0)
10303e519524SHoward Hinnant        {
10313e519524SHoward Hinnant            __m = ~__storage_type(0) >> (__bits_per_word - __n);
10323e519524SHoward Hinnant            __storage_type __b = *__first1.__seg_ & __m;
1033ce48a113SHoward Hinnant            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
10343e519524SHoward Hinnant            __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
10353e519524SHoward Hinnant            if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
10363e519524SHoward Hinnant                return false;
10373e519524SHoward Hinnant            __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
10383e519524SHoward Hinnant            __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_)  % __bits_per_word);
10393e519524SHoward Hinnant            __n -= __dn;
10403e519524SHoward Hinnant            if (__n > 0)
10413e519524SHoward Hinnant            {
10423e519524SHoward Hinnant                __m = ~__storage_type(0) >> (__bits_per_word - __n);
10433e519524SHoward Hinnant                if ((*__first2.__seg_ & __m) != (__b >> __dn))
10443e519524SHoward Hinnant                    return false;
10453e519524SHoward Hinnant            }
10463e519524SHoward Hinnant        }
10473e519524SHoward Hinnant    }
10483e519524SHoward Hinnant    return true;
10493e519524SHoward Hinnant}
10503e519524SHoward Hinnant
10511237dccaSHoward Hinnanttemplate <class _Cp, bool _IC1, bool _IC2>
10523e519524SHoward Hinnantbool
10531237dccaSHoward Hinnant__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
10541237dccaSHoward Hinnant                __bit_iterator<_Cp, _IC2> __first2)
10553e519524SHoward Hinnant{
10561237dccaSHoward Hinnant    typedef __bit_iterator<_Cp, _IC1> _It;
10573e519524SHoward Hinnant    typedef  typename _It::difference_type difference_type;
10583e519524SHoward Hinnant    typedef typename _It::__storage_type __storage_type;
1059aec08784SEric Fiselier    static const int __bits_per_word = _It::__bits_per_word;
10603e519524SHoward Hinnant    difference_type __n = __last1 - __first1;
10613e519524SHoward Hinnant    if (__n > 0)
10623e519524SHoward Hinnant    {
10633e519524SHoward Hinnant        // do first word
10643e519524SHoward Hinnant        if (__first1.__ctz_ != 0)
10653e519524SHoward Hinnant        {
10663e519524SHoward Hinnant            unsigned __clz = __bits_per_word - __first1.__ctz_;
1067ce48a113SHoward Hinnant            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
10683e519524SHoward Hinnant            __n -= __dn;
10693e519524SHoward Hinnant            __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
10703e519524SHoward Hinnant            if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
10713e519524SHoward Hinnant                return false;
10723e519524SHoward Hinnant            ++__first2.__seg_;
10733e519524SHoward Hinnant            ++__first1.__seg_;
10743e519524SHoward Hinnant            // __first1.__ctz_ = 0;
10753e519524SHoward Hinnant            // __first2.__ctz_ = 0;
10763e519524SHoward Hinnant        }
10773e519524SHoward Hinnant        // __first1.__ctz_ == 0;
10783e519524SHoward Hinnant        // __first2.__ctz_ == 0;
10793e519524SHoward Hinnant        // do middle words
10803e519524SHoward Hinnant        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
10813e519524SHoward Hinnant            if (*__first2.__seg_ != *__first1.__seg_)
10823e519524SHoward Hinnant                return false;
10833e519524SHoward Hinnant        // do last word
10843e519524SHoward Hinnant        if (__n > 0)
10853e519524SHoward Hinnant        {
10863e519524SHoward Hinnant            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
10873e519524SHoward Hinnant            if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
10883e519524SHoward Hinnant                return false;
10893e519524SHoward Hinnant        }
10903e519524SHoward Hinnant    }
10913e519524SHoward Hinnant    return true;
10923e519524SHoward Hinnant}
10933e519524SHoward Hinnant
1094c003db1fSHoward Hinnanttemplate <class _Cp, bool _IC1, bool _IC2>
109543d99238SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
10963e519524SHoward Hinnantbool
1097c003db1fSHoward Hinnantequal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
10983e519524SHoward Hinnant{
10993e519524SHoward Hinnant    if (__first1.__ctz_ == __first2.__ctz_)
1100781c476cSArthur O'Dwyer        return _VSTD::__equal_aligned(__first1, __last1, __first2);
1101781c476cSArthur O'Dwyer    return _VSTD::__equal_unaligned(__first1, __last1, __first2);
11023e519524SHoward Hinnant}
11033e519524SHoward Hinnant
11040ae9efebSHoward Hinnanttemplate <class _Cp, bool _IsConst,
11050ae9efebSHoward Hinnant          typename _Cp::__storage_type>
11063e519524SHoward Hinnantclass __bit_iterator
11073e519524SHoward Hinnant{
11083e519524SHoward Hinnantpublic:
1109c003db1fSHoward Hinnant    typedef typename _Cp::difference_type                                                          difference_type;
11103e519524SHoward Hinnant    typedef bool                                                                                  value_type;
11113e519524SHoward Hinnant    typedef __bit_iterator                                                                        pointer;
1112c003db1fSHoward Hinnant    typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference;
11133e519524SHoward Hinnant    typedef random_access_iterator_tag                                                            iterator_category;
11143e519524SHoward Hinnant
11153e519524SHoward Hinnantprivate:
1116c003db1fSHoward Hinnant    typedef typename _Cp::__storage_type                                           __storage_type;
1117c003db1fSHoward Hinnant    typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer,
1118c003db1fSHoward Hinnant                                           typename _Cp::__storage_pointer>::type  __storage_pointer;
1119c003db1fSHoward Hinnant    static const unsigned __bits_per_word = _Cp::__bits_per_word;
11203e519524SHoward Hinnant
11213e519524SHoward Hinnant    __storage_pointer __seg_;
11223e519524SHoward Hinnant    unsigned          __ctz_;
11233e519524SHoward Hinnant
11243e519524SHoward Hinnantpublic:
112536b2a3b0SMarshall Clow    _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
112636b2a3b0SMarshall Clow#if _LIBCPP_STD_VER > 11
112736b2a3b0SMarshall Clow    : __seg_(nullptr), __ctz_(0)
112836b2a3b0SMarshall Clow#endif
112936b2a3b0SMarshall Clow    {}
11303e519524SHoward Hinnant
113170d94c3fSArthur O'Dwyer    // When _IsConst=false, this is the copy constructor.
113270d94c3fSArthur O'Dwyer    // It is non-trivial. Making it trivial would break ABI.
113370d94c3fSArthur O'Dwyer    // When _IsConst=true, this is a converting constructor;
113470d94c3fSArthur O'Dwyer    // the copy and move constructors are implicitly generated
113570d94c3fSArthur O'Dwyer    // and trivial.
1136d368a84cSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
113770d94c3fSArthur O'Dwyer    __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
11383e519524SHoward Hinnant        : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
11393e519524SHoward Hinnant
114070d94c3fSArthur O'Dwyer    // When _IsConst=false, we have a user-provided copy constructor,
114170d94c3fSArthur O'Dwyer    // so we must also provide a copy assignment operator because
114270d94c3fSArthur O'Dwyer    // the implicit generation of a defaulted one is deprecated.
114370d94c3fSArthur O'Dwyer    // When _IsConst=true, the assignment operators are
114470d94c3fSArthur O'Dwyer    // implicitly generated and trivial.
1145a829443cSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
114670d94c3fSArthur O'Dwyer    __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
114770d94c3fSArthur O'Dwyer        __seg_ = __it.__seg_;
114870d94c3fSArthur O'Dwyer        __ctz_ = __it.__ctz_;
114970d94c3fSArthur O'Dwyer        return *this;
115070d94c3fSArthur O'Dwyer    }
1151a829443cSEric Fiselier
1152d368a84cSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
1153d368a84cSHoward Hinnant        {return reference(__seg_, __storage_type(1) << __ctz_);}
11543e519524SHoward Hinnant
11553e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()
11563e519524SHoward Hinnant    {
11573e519524SHoward Hinnant        if (__ctz_ != __bits_per_word-1)
11583e519524SHoward Hinnant            ++__ctz_;
11593e519524SHoward Hinnant        else
11603e519524SHoward Hinnant        {
11613e519524SHoward Hinnant            __ctz_ = 0;
11623e519524SHoward Hinnant            ++__seg_;
11633e519524SHoward Hinnant        }
11643e519524SHoward Hinnant        return *this;
11653e519524SHoward Hinnant    }
11663e519524SHoward Hinnant
11673e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int)
11683e519524SHoward Hinnant    {
11693e519524SHoward Hinnant        __bit_iterator __tmp = *this;
11703e519524SHoward Hinnant        ++(*this);
11713e519524SHoward Hinnant        return __tmp;
11723e519524SHoward Hinnant    }
11733e519524SHoward Hinnant
11743e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--()
11753e519524SHoward Hinnant    {
11763e519524SHoward Hinnant        if (__ctz_ != 0)
11773e519524SHoward Hinnant            --__ctz_;
11783e519524SHoward Hinnant        else
11793e519524SHoward Hinnant        {
11803e519524SHoward Hinnant            __ctz_ = __bits_per_word - 1;
11813e519524SHoward Hinnant            --__seg_;
11823e519524SHoward Hinnant        }
11833e519524SHoward Hinnant        return *this;
11843e519524SHoward Hinnant    }
11853e519524SHoward Hinnant
11863e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int)
11873e519524SHoward Hinnant    {
11883e519524SHoward Hinnant        __bit_iterator __tmp = *this;
11893e519524SHoward Hinnant        --(*this);
11903e519524SHoward Hinnant        return __tmp;
11913e519524SHoward Hinnant    }
11923e519524SHoward Hinnant
11933e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n)
11943e519524SHoward Hinnant    {
11953e519524SHoward Hinnant        if (__n >= 0)
11963e519524SHoward Hinnant            __seg_ += (__n + __ctz_) / __bits_per_word;
11973e519524SHoward Hinnant        else
11983e519524SHoward Hinnant            __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1)
11993e519524SHoward Hinnant                    / static_cast<difference_type>(__bits_per_word);
12003e519524SHoward Hinnant        __n &= (__bits_per_word - 1);
12013e519524SHoward Hinnant        __ctz_ = static_cast<unsigned>((__n + __ctz_)  % __bits_per_word);
12023e519524SHoward Hinnant        return *this;
12033e519524SHoward Hinnant    }
12043e519524SHoward Hinnant
12053e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n)
12063e519524SHoward Hinnant    {
12073e519524SHoward Hinnant        return *this += -__n;
12083e519524SHoward Hinnant    }
12093e519524SHoward Hinnant
12103e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const
12113e519524SHoward Hinnant    {
12123e519524SHoward Hinnant        __bit_iterator __t(*this);
12133e519524SHoward Hinnant        __t += __n;
12143e519524SHoward Hinnant        return __t;
12153e519524SHoward Hinnant    }
12163e519524SHoward Hinnant
12173e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const
12183e519524SHoward Hinnant    {
12193e519524SHoward Hinnant        __bit_iterator __t(*this);
12203e519524SHoward Hinnant        __t -= __n;
12213e519524SHoward Hinnant        return __t;
12223e519524SHoward Hinnant    }
12233e519524SHoward Hinnant
12243e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
12253e519524SHoward Hinnant    friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}
12263e519524SHoward Hinnant
12273e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
12283e519524SHoward Hinnant    friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)
12293e519524SHoward Hinnant        {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}
12303e519524SHoward Hinnant
12313e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);}
12323e519524SHoward Hinnant
12333e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
12343e519524SHoward Hinnant        {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}
12353e519524SHoward Hinnant
12363e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
12373e519524SHoward Hinnant        {return !(__x == __y);}
12383e519524SHoward Hinnant
12393e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
12403e519524SHoward Hinnant        {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}
12413e519524SHoward Hinnant
12423e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
12433e519524SHoward Hinnant        {return __y < __x;}
12443e519524SHoward Hinnant
12453e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)
12463e519524SHoward Hinnant        {return !(__y < __x);}
12473e519524SHoward Hinnant
12483e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)
12493e519524SHoward Hinnant        {return !(__x < __y);}
12503e519524SHoward Hinnant
12513e519524SHoward Hinnantprivate:
12523e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1253*f86c2b6fSArthur O'Dwyer    explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
1254d368a84cSHoward Hinnant        : __seg_(__s), __ctz_(__ctz) {}
12553e519524SHoward Hinnant
1256c003db1fSHoward Hinnant    friend typename _Cp::__self;
1257541f9e28SEric Fiselier
1258c003db1fSHoward Hinnant    friend class __bit_reference<_Cp>;
1259c003db1fSHoward Hinnant    friend class __bit_const_reference<_Cp>;
1260c003db1fSHoward Hinnant    friend class __bit_iterator<_Cp, true>;
1261c003db1fSHoward Hinnant    template <class _Dp> friend struct __bit_array;
1262c003db1fSHoward Hinnant    template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1263c003db1fSHoward Hinnant    template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1264c003db1fSHoward Hinnant    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
1265c003db1fSHoward Hinnant                                                                                  __bit_iterator<_Dp, _IC> __last,
1266c003db1fSHoward Hinnant                                                                                  __bit_iterator<_Dp, false> __result);
1267c003db1fSHoward Hinnant    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,
1268c003db1fSHoward Hinnant                                                                                    __bit_iterator<_Dp, _IC> __last,
1269c003db1fSHoward Hinnant                                                                                    __bit_iterator<_Dp, false> __result);
1270c003db1fSHoward Hinnant    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,
1271c003db1fSHoward Hinnant                                                                        __bit_iterator<_Dp, _IC> __last,
1272c003db1fSHoward Hinnant                                                                        __bit_iterator<_Dp, false> __result);
1273c003db1fSHoward Hinnant    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first,
1274c003db1fSHoward Hinnant                                                                                           __bit_iterator<_Dp, _IC> __last,
1275c003db1fSHoward Hinnant                                                                                           __bit_iterator<_Dp, false> __result);
1276c003db1fSHoward Hinnant    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first,
1277c003db1fSHoward Hinnant                                                                                             __bit_iterator<_Dp, _IC> __last,
1278c003db1fSHoward Hinnant                                                                                             __bit_iterator<_Dp, false> __result);
1279c003db1fSHoward Hinnant    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
1280c003db1fSHoward Hinnant                                                                                 __bit_iterator<_Dp, _IC> __last,
1281c003db1fSHoward Hinnant                                                                                 __bit_iterator<_Dp, false> __result);
1282dbe81119SHoward Hinnant    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
1283dbe81119SHoward Hinnant                                                                                           __bit_iterator<__C1, false>,
1284dbe81119SHoward Hinnant                                                                                           __bit_iterator<__C2, false>);
1285dbe81119SHoward Hinnant    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,
1286dbe81119SHoward Hinnant                                                                                             __bit_iterator<__C1, false>,
1287dbe81119SHoward Hinnant                                                                                             __bit_iterator<__C2, false>);
1288dbe81119SHoward Hinnant    template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
1289dbe81119SHoward Hinnant                                                                                 __bit_iterator<__C1, false>,
1290dbe81119SHoward Hinnant                                                                                 __bit_iterator<__C2, false>);
1291c003db1fSHoward Hinnant    template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
1292c003db1fSHoward Hinnant                                                                __bit_iterator<_Dp, false>,
1293c003db1fSHoward Hinnant                                                                __bit_iterator<_Dp, false>);
12941237dccaSHoward Hinnant    template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
12951237dccaSHoward Hinnant                                                    __bit_iterator<_Dp, _IC1>,
12961237dccaSHoward Hinnant                                                    __bit_iterator<_Dp, _IC2>);
12971237dccaSHoward Hinnant    template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
12981237dccaSHoward Hinnant                                                      __bit_iterator<_Dp, _IC1>,
12991237dccaSHoward Hinnant                                                      __bit_iterator<_Dp, _IC2>);
1300c003db1fSHoward Hinnant    template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>,
1301c003db1fSHoward Hinnant                                                                __bit_iterator<_Dp, _IC1>,
1302c003db1fSHoward Hinnant                                                                __bit_iterator<_Dp, _IC2>);
1303423a8d77SHoward Hinnant    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>,
1304c003db1fSHoward Hinnant                                                                          typename _Dp::size_type);
1305423a8d77SHoward Hinnant    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>,
1306c003db1fSHoward Hinnant                                                                           typename _Dp::size_type);
1307423a8d77SHoward Hinnant    template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1308423a8d77SHoward Hinnant                   __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1309423a8d77SHoward Hinnant    template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1310423a8d77SHoward Hinnant                   __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
13113e519524SHoward Hinnant};
13123e519524SHoward Hinnant
13133e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
13143e519524SHoward Hinnant
1315a016efb1SEric Fiselier_LIBCPP_POP_MACROS
1316a016efb1SEric Fiselier
13173e519524SHoward Hinnant#endif // _LIBCPP___BIT_REFERENCE
1318