xref: /openbsd-src/gnu/llvm/libcxx/include/__bit_reference (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
246035553Spatrick//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP___BIT_REFERENCE
1146035553Spatrick#define _LIBCPP___BIT_REFERENCE
1246035553Spatrick
13*4bdff4beSrobert#include <__algorithm/copy_n.h>
14*4bdff4beSrobert#include <__algorithm/fill_n.h>
15*4bdff4beSrobert#include <__algorithm/min.h>
16*4bdff4beSrobert#include <__bit/countr.h>
17*4bdff4beSrobert#include <__bit/popcount.h>
1846035553Spatrick#include <__config>
19*4bdff4beSrobert#include <__iterator/iterator_traits.h>
20*4bdff4beSrobert#include <__memory/construct_at.h>
21*4bdff4beSrobert#include <__memory/pointer_traits.h>
22*4bdff4beSrobert#include <cstring>
23*4bdff4beSrobert#include <type_traits>
2446035553Spatrick
2546035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2646035553Spatrick#  pragma GCC system_header
2746035553Spatrick#endif
2846035553Spatrick
2946035553Spatrick_LIBCPP_PUSH_MACROS
3046035553Spatrick#include <__undef_macros>
3146035553Spatrick
3246035553Spatrick
3346035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
3446035553Spatrick
3546035553Spatricktemplate <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;
3646035553Spatricktemplate <class _Cp> class __bit_const_reference;
3746035553Spatrick
3846035553Spatricktemplate <class _Tp>
3946035553Spatrickstruct __has_storage_type
4046035553Spatrick{
4146035553Spatrick    static const bool value = false;
4246035553Spatrick};
4346035553Spatrick
4446035553Spatricktemplate <class _Cp, bool = __has_storage_type<_Cp>::value>
4546035553Spatrickclass __bit_reference
4646035553Spatrick{
4746035553Spatrick    typedef typename _Cp::__storage_type    __storage_type;
4846035553Spatrick    typedef typename _Cp::__storage_pointer __storage_pointer;
4946035553Spatrick
5046035553Spatrick    __storage_pointer __seg_;
5146035553Spatrick    __storage_type    __mask_;
5246035553Spatrick
5346035553Spatrick    friend typename _Cp::__self;
5446035553Spatrick
5546035553Spatrick    friend class __bit_const_reference<_Cp>;
5646035553Spatrick    friend class __bit_iterator<_Cp, false>;
5746035553Spatrickpublic:
58*4bdff4beSrobert    using __container = typename _Cp::__self;
59*4bdff4beSrobert
60*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
6146035553Spatrick    __bit_reference(const __bit_reference&) = default;
6246035553Spatrick
63*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT
6446035553Spatrick        {return static_cast<bool>(*__seg_ & __mask_);}
65*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator ~() const _NOEXCEPT
6646035553Spatrick        {return !static_cast<bool>(*this);}
6746035553Spatrick
68*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
6946035553Spatrick    __bit_reference& operator=(bool __x) _NOEXCEPT
7046035553Spatrick    {
7146035553Spatrick        if (__x)
7246035553Spatrick            *__seg_ |= __mask_;
7346035553Spatrick        else
7446035553Spatrick            *__seg_ &= ~__mask_;
7546035553Spatrick        return *this;
7646035553Spatrick    }
7746035553Spatrick
78*4bdff4beSrobert#if _LIBCPP_STD_VER > 20
79*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept {
80*4bdff4beSrobert        if (__x)
81*4bdff4beSrobert            *__seg_ |= __mask_;
82*4bdff4beSrobert        else
83*4bdff4beSrobert            *__seg_ &= ~__mask_;
84*4bdff4beSrobert        return *this;
85*4bdff4beSrobert    }
86*4bdff4beSrobert#endif
87*4bdff4beSrobert
88*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
8946035553Spatrick    __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
9046035553Spatrick        {return operator=(static_cast<bool>(__x));}
9146035553Spatrick
92*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
93*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
94*4bdff4beSrobert        {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));}
9546035553Spatrickprivate:
96*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
97*4bdff4beSrobert    explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
9846035553Spatrick        : __seg_(__s), __mask_(__m) {}
9946035553Spatrick};
10046035553Spatrick
10146035553Spatricktemplate <class _Cp>
10246035553Spatrickclass __bit_reference<_Cp, false>
10346035553Spatrick{
10446035553Spatrick};
10546035553Spatrick
10646035553Spatricktemplate <class _Cp>
107*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
10846035553Spatrickvoid
10946035553Spatrickswap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
11046035553Spatrick{
11146035553Spatrick    bool __t = __x;
11246035553Spatrick    __x = __y;
11346035553Spatrick    __y = __t;
11446035553Spatrick}
11546035553Spatrick
11646035553Spatricktemplate <class _Cp, class _Dp>
117*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
11846035553Spatrickvoid
11946035553Spatrickswap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
12046035553Spatrick{
12146035553Spatrick    bool __t = __x;
12246035553Spatrick    __x = __y;
12346035553Spatrick    __y = __t;
12446035553Spatrick}
12546035553Spatrick
12646035553Spatricktemplate <class _Cp>
127*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
12846035553Spatrickvoid
12946035553Spatrickswap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
13046035553Spatrick{
13146035553Spatrick    bool __t = __x;
13246035553Spatrick    __x = __y;
13346035553Spatrick    __y = __t;
13446035553Spatrick}
13546035553Spatrick
13646035553Spatricktemplate <class _Cp>
137*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
13846035553Spatrickvoid
13946035553Spatrickswap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
14046035553Spatrick{
14146035553Spatrick    bool __t = __x;
14246035553Spatrick    __x = __y;
14346035553Spatrick    __y = __t;
14446035553Spatrick}
14546035553Spatrick
14646035553Spatricktemplate <class _Cp>
14746035553Spatrickclass __bit_const_reference
14846035553Spatrick{
14946035553Spatrick    typedef typename _Cp::__storage_type          __storage_type;
15046035553Spatrick    typedef typename _Cp::__const_storage_pointer __storage_pointer;
15146035553Spatrick
15246035553Spatrick    __storage_pointer        __seg_;
15346035553Spatrick    __storage_type __mask_;
15446035553Spatrick
15546035553Spatrick    friend typename _Cp::__self;
15646035553Spatrick    friend class __bit_iterator<_Cp, true>;
15746035553Spatrickpublic:
15846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
15946035553Spatrick    __bit_const_reference(const __bit_const_reference&) = default;
16046035553Spatrick
161*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
16246035553Spatrick    __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
16346035553Spatrick        : __seg_(__x.__seg_), __mask_(__x.__mask_) {}
16446035553Spatrick
16546035553Spatrick    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT
16646035553Spatrick        {return static_cast<bool>(*__seg_ & __mask_);}
16746035553Spatrick
168*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
169*4bdff4beSrobert        {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));}
17046035553Spatrickprivate:
17146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
17246035553Spatrick    _LIBCPP_CONSTEXPR
173*4bdff4beSrobert    explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
17446035553Spatrick        : __seg_(__s), __mask_(__m) {}
17546035553Spatrick
17646035553Spatrick    __bit_const_reference& operator=(const __bit_const_reference&) = delete;
17746035553Spatrick};
17846035553Spatrick
17946035553Spatrick// find
18046035553Spatrick
18146035553Spatricktemplate <class _Cp, bool _IsConst>
182*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst>
18346035553Spatrick__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
18446035553Spatrick{
18546035553Spatrick    typedef __bit_iterator<_Cp, _IsConst> _It;
18646035553Spatrick    typedef typename _It::__storage_type __storage_type;
187*4bdff4beSrobert    const int __bits_per_word = _It::__bits_per_word;
18846035553Spatrick    // do first partial word
18946035553Spatrick    if (__first.__ctz_ != 0)
19046035553Spatrick    {
19146035553Spatrick        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
19246035553Spatrick        __storage_type __dn = _VSTD::min(__clz_f, __n);
19346035553Spatrick        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
19446035553Spatrick        __storage_type __b = *__first.__seg_ & __m;
19546035553Spatrick        if (__b)
19646035553Spatrick            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
19746035553Spatrick        if (__n == __dn)
19846035553Spatrick            return __first + __n;
19946035553Spatrick        __n -= __dn;
20046035553Spatrick        ++__first.__seg_;
20146035553Spatrick    }
20246035553Spatrick    // do middle whole words
20346035553Spatrick    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
20446035553Spatrick        if (*__first.__seg_)
20546035553Spatrick            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(*__first.__seg_)));
20646035553Spatrick    // do last partial word
20746035553Spatrick    if (__n > 0)
20846035553Spatrick    {
20946035553Spatrick        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
21046035553Spatrick        __storage_type __b = *__first.__seg_ & __m;
21146035553Spatrick        if (__b)
21246035553Spatrick            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
21346035553Spatrick    }
21446035553Spatrick    return _It(__first.__seg_, static_cast<unsigned>(__n));
21546035553Spatrick}
21646035553Spatrick
21746035553Spatricktemplate <class _Cp, bool _IsConst>
218*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst>
21946035553Spatrick__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
22046035553Spatrick{
22146035553Spatrick    typedef __bit_iterator<_Cp, _IsConst> _It;
22246035553Spatrick    typedef typename _It::__storage_type __storage_type;
22346035553Spatrick    const int __bits_per_word = _It::__bits_per_word;
22446035553Spatrick    // do first partial word
22546035553Spatrick    if (__first.__ctz_ != 0)
22646035553Spatrick    {
22746035553Spatrick        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
22846035553Spatrick        __storage_type __dn = _VSTD::min(__clz_f, __n);
22946035553Spatrick        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
23046035553Spatrick        __storage_type __b = ~*__first.__seg_ & __m;
23146035553Spatrick        if (__b)
23246035553Spatrick            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
23346035553Spatrick        if (__n == __dn)
23446035553Spatrick            return __first + __n;
23546035553Spatrick        __n -= __dn;
23646035553Spatrick        ++__first.__seg_;
23746035553Spatrick    }
23846035553Spatrick    // do middle whole words
23946035553Spatrick    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
24046035553Spatrick    {
24146035553Spatrick        __storage_type __b = ~*__first.__seg_;
24246035553Spatrick        if (__b)
24346035553Spatrick            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
24446035553Spatrick    }
24546035553Spatrick    // do last partial word
24646035553Spatrick    if (__n > 0)
24746035553Spatrick    {
24846035553Spatrick        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
24946035553Spatrick        __storage_type __b = ~*__first.__seg_ & __m;
25046035553Spatrick        if (__b)
25146035553Spatrick            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
25246035553Spatrick    }
25346035553Spatrick    return _It(__first.__seg_, static_cast<unsigned>(__n));
25446035553Spatrick}
25546035553Spatrick
25646035553Spatricktemplate <class _Cp, bool _IsConst, class _Tp>
257*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
25846035553Spatrick__bit_iterator<_Cp, _IsConst>
259*4bdff4beSrobertfind(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value)
26046035553Spatrick{
261*4bdff4beSrobert    if (static_cast<bool>(__value))
26276d0caaeSpatrick        return _VSTD::__find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
26376d0caaeSpatrick    return _VSTD::__find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
26446035553Spatrick}
26546035553Spatrick
26646035553Spatrick// count
26746035553Spatrick
26846035553Spatricktemplate <class _Cp, bool _IsConst>
269*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __bit_iterator<_Cp, _IsConst>::difference_type
27046035553Spatrick__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
27146035553Spatrick{
27246035553Spatrick    typedef __bit_iterator<_Cp, _IsConst> _It;
27346035553Spatrick    typedef typename _It::__storage_type __storage_type;
27446035553Spatrick    typedef typename _It::difference_type difference_type;
27546035553Spatrick    const int __bits_per_word = _It::__bits_per_word;
27646035553Spatrick    difference_type __r = 0;
27746035553Spatrick    // do first partial word
27846035553Spatrick    if (__first.__ctz_ != 0)
27946035553Spatrick    {
28046035553Spatrick        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
28146035553Spatrick        __storage_type __dn = _VSTD::min(__clz_f, __n);
28246035553Spatrick        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
28346035553Spatrick        __r = _VSTD::__libcpp_popcount(*__first.__seg_ & __m);
28446035553Spatrick        __n -= __dn;
28546035553Spatrick        ++__first.__seg_;
28646035553Spatrick    }
28746035553Spatrick    // do middle whole words
28846035553Spatrick    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
28946035553Spatrick        __r += _VSTD::__libcpp_popcount(*__first.__seg_);
29046035553Spatrick    // do last partial word
29146035553Spatrick    if (__n > 0)
29246035553Spatrick    {
29346035553Spatrick        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
29446035553Spatrick        __r += _VSTD::__libcpp_popcount(*__first.__seg_ & __m);
29546035553Spatrick    }
29646035553Spatrick    return __r;
29746035553Spatrick}
29846035553Spatrick
29946035553Spatricktemplate <class _Cp, bool _IsConst>
300*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI typename __bit_iterator<_Cp, _IsConst>::difference_type
30146035553Spatrick__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
30246035553Spatrick{
30346035553Spatrick    typedef __bit_iterator<_Cp, _IsConst> _It;
30446035553Spatrick    typedef typename _It::__storage_type __storage_type;
30546035553Spatrick    typedef typename _It::difference_type difference_type;
30646035553Spatrick    const int __bits_per_word = _It::__bits_per_word;
30746035553Spatrick    difference_type __r = 0;
30846035553Spatrick    // do first partial word
30946035553Spatrick    if (__first.__ctz_ != 0)
31046035553Spatrick    {
31146035553Spatrick        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
31246035553Spatrick        __storage_type __dn = _VSTD::min(__clz_f, __n);
31346035553Spatrick        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
31446035553Spatrick        __r = _VSTD::__libcpp_popcount(~*__first.__seg_ & __m);
31546035553Spatrick        __n -= __dn;
31646035553Spatrick        ++__first.__seg_;
31746035553Spatrick    }
31846035553Spatrick    // do middle whole words
31946035553Spatrick    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
32046035553Spatrick        __r += _VSTD::__libcpp_popcount(~*__first.__seg_);
32146035553Spatrick    // do last partial word
32246035553Spatrick    if (__n > 0)
32346035553Spatrick    {
32446035553Spatrick        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
32546035553Spatrick        __r += _VSTD::__libcpp_popcount(~*__first.__seg_ & __m);
32646035553Spatrick    }
32746035553Spatrick    return __r;
32846035553Spatrick}
32946035553Spatrick
33046035553Spatricktemplate <class _Cp, bool _IsConst, class _Tp>
33146035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
33246035553Spatricktypename __bit_iterator<_Cp, _IsConst>::difference_type
333*4bdff4beSrobertcount(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value)
33446035553Spatrick{
335*4bdff4beSrobert    if (static_cast<bool>(__value))
33676d0caaeSpatrick        return _VSTD::__count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
33776d0caaeSpatrick    return _VSTD::__count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
33846035553Spatrick}
33946035553Spatrick
34046035553Spatrick// fill_n
34146035553Spatrick
34246035553Spatricktemplate <class _Cp>
343*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
34446035553Spatrick__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
34546035553Spatrick{
34646035553Spatrick    typedef __bit_iterator<_Cp, false> _It;
34746035553Spatrick    typedef typename _It::__storage_type __storage_type;
34846035553Spatrick    const int __bits_per_word = _It::__bits_per_word;
34946035553Spatrick    // do first partial word
35046035553Spatrick    if (__first.__ctz_ != 0)
35146035553Spatrick    {
35246035553Spatrick        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
35346035553Spatrick        __storage_type __dn = _VSTD::min(__clz_f, __n);
35446035553Spatrick        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
35546035553Spatrick        *__first.__seg_ &= ~__m;
35646035553Spatrick        __n -= __dn;
35746035553Spatrick        ++__first.__seg_;
35846035553Spatrick    }
35946035553Spatrick    // do middle whole words
36046035553Spatrick    __storage_type __nw = __n / __bits_per_word;
361*4bdff4beSrobert    std::fill_n(std::__to_address(__first.__seg_), __nw, 0);
36246035553Spatrick    __n -= __nw * __bits_per_word;
36346035553Spatrick    // do last partial word
36446035553Spatrick    if (__n > 0)
36546035553Spatrick    {
36646035553Spatrick        __first.__seg_ += __nw;
36746035553Spatrick        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
36846035553Spatrick        *__first.__seg_ &= ~__m;
36946035553Spatrick    }
37046035553Spatrick}
37146035553Spatrick
37246035553Spatricktemplate <class _Cp>
373*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
37446035553Spatrick__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
37546035553Spatrick{
37646035553Spatrick    typedef __bit_iterator<_Cp, false> _It;
37746035553Spatrick    typedef typename _It::__storage_type __storage_type;
37846035553Spatrick    const int __bits_per_word = _It::__bits_per_word;
37946035553Spatrick    // do first partial word
38046035553Spatrick    if (__first.__ctz_ != 0)
38146035553Spatrick    {
38246035553Spatrick        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
38346035553Spatrick        __storage_type __dn = _VSTD::min(__clz_f, __n);
38446035553Spatrick        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
38546035553Spatrick        *__first.__seg_ |= __m;
38646035553Spatrick        __n -= __dn;
38746035553Spatrick        ++__first.__seg_;
38846035553Spatrick    }
38946035553Spatrick    // do middle whole words
39046035553Spatrick    __storage_type __nw = __n / __bits_per_word;
391*4bdff4beSrobert    // __storage_type is always an unsigned type, so -1 sets all bits
392*4bdff4beSrobert    std::fill_n(std::__to_address(__first.__seg_), __nw, static_cast<__storage_type>(-1));
39346035553Spatrick    __n -= __nw * __bits_per_word;
39446035553Spatrick    // do last partial word
39546035553Spatrick    if (__n > 0)
39646035553Spatrick    {
39746035553Spatrick        __first.__seg_ += __nw;
39846035553Spatrick        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
39946035553Spatrick        *__first.__seg_ |= __m;
40046035553Spatrick    }
40146035553Spatrick}
40246035553Spatrick
40346035553Spatricktemplate <class _Cp>
404*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
40546035553Spatrickvoid
406*4bdff4beSrobertfill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value)
40746035553Spatrick{
40846035553Spatrick    if (__n > 0)
40946035553Spatrick    {
410*4bdff4beSrobert        if (__value)
41176d0caaeSpatrick            _VSTD::__fill_n_true(__first, __n);
41246035553Spatrick        else
41376d0caaeSpatrick            _VSTD::__fill_n_false(__first, __n);
41446035553Spatrick    }
41546035553Spatrick}
41646035553Spatrick
41746035553Spatrick// fill
41846035553Spatrick
41946035553Spatricktemplate <class _Cp>
420*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
42146035553Spatrickvoid
422*4bdff4beSrobertfill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value)
42346035553Spatrick{
424*4bdff4beSrobert    _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value);
42546035553Spatrick}
42646035553Spatrick
42746035553Spatrick// copy
42846035553Spatrick
42946035553Spatricktemplate <class _Cp, bool _IsConst>
430*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
43146035553Spatrick__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
43246035553Spatrick                                                     __bit_iterator<_Cp, false> __result)
43346035553Spatrick{
43446035553Spatrick    typedef __bit_iterator<_Cp, _IsConst> _In;
43546035553Spatrick    typedef  typename _In::difference_type difference_type;
43646035553Spatrick    typedef typename _In::__storage_type __storage_type;
43746035553Spatrick    const int __bits_per_word = _In::__bits_per_word;
43846035553Spatrick    difference_type __n = __last - __first;
43946035553Spatrick    if (__n > 0)
44046035553Spatrick    {
44146035553Spatrick        // do first word
44246035553Spatrick        if (__first.__ctz_ != 0)
44346035553Spatrick        {
44446035553Spatrick            unsigned __clz = __bits_per_word - __first.__ctz_;
44546035553Spatrick            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
44646035553Spatrick            __n -= __dn;
44746035553Spatrick            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
44846035553Spatrick            __storage_type __b = *__first.__seg_ & __m;
44946035553Spatrick            *__result.__seg_ &= ~__m;
45046035553Spatrick            *__result.__seg_ |= __b;
45146035553Spatrick            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
45246035553Spatrick            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
45346035553Spatrick            ++__first.__seg_;
45446035553Spatrick            // __first.__ctz_ = 0;
45546035553Spatrick        }
45646035553Spatrick        // __first.__ctz_ == 0;
45746035553Spatrick        // do middle words
45846035553Spatrick        __storage_type __nw = __n / __bits_per_word;
459*4bdff4beSrobert        std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_));
46046035553Spatrick        __n -= __nw * __bits_per_word;
46146035553Spatrick        __result.__seg_ += __nw;
46246035553Spatrick        // do last word
46346035553Spatrick        if (__n > 0)
46446035553Spatrick        {
46546035553Spatrick            __first.__seg_ += __nw;
46646035553Spatrick            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
46746035553Spatrick            __storage_type __b = *__first.__seg_ & __m;
46846035553Spatrick            *__result.__seg_ &= ~__m;
46946035553Spatrick            *__result.__seg_ |= __b;
47046035553Spatrick            __result.__ctz_ = static_cast<unsigned>(__n);
47146035553Spatrick        }
47246035553Spatrick    }
47346035553Spatrick    return __result;
47446035553Spatrick}
47546035553Spatrick
47646035553Spatricktemplate <class _Cp, bool _IsConst>
477*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
47846035553Spatrick__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
47946035553Spatrick                                                       __bit_iterator<_Cp, false> __result)
48046035553Spatrick{
48146035553Spatrick    typedef __bit_iterator<_Cp, _IsConst> _In;
48246035553Spatrick    typedef  typename _In::difference_type difference_type;
48346035553Spatrick    typedef typename _In::__storage_type __storage_type;
484*4bdff4beSrobert    const int __bits_per_word = _In::__bits_per_word;
48546035553Spatrick    difference_type __n = __last - __first;
48646035553Spatrick    if (__n > 0)
48746035553Spatrick    {
48846035553Spatrick        // do first word
48946035553Spatrick        if (__first.__ctz_ != 0)
49046035553Spatrick        {
49146035553Spatrick            unsigned __clz_f = __bits_per_word - __first.__ctz_;
49246035553Spatrick            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
49346035553Spatrick            __n -= __dn;
49446035553Spatrick            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
49546035553Spatrick            __storage_type __b = *__first.__seg_ & __m;
49646035553Spatrick            unsigned __clz_r = __bits_per_word - __result.__ctz_;
49746035553Spatrick            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
49846035553Spatrick            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
49946035553Spatrick            *__result.__seg_ &= ~__m;
50046035553Spatrick            if (__result.__ctz_ > __first.__ctz_)
50146035553Spatrick                *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
50246035553Spatrick            else
50346035553Spatrick                *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
50446035553Spatrick            __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
50546035553Spatrick            __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_)  % __bits_per_word);
50646035553Spatrick            __dn -= __ddn;
50746035553Spatrick            if (__dn > 0)
50846035553Spatrick            {
50946035553Spatrick                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
51046035553Spatrick                *__result.__seg_ &= ~__m;
51146035553Spatrick                *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
51246035553Spatrick                __result.__ctz_ = static_cast<unsigned>(__dn);
51346035553Spatrick            }
51446035553Spatrick            ++__first.__seg_;
51546035553Spatrick            // __first.__ctz_ = 0;
51646035553Spatrick        }
51746035553Spatrick        // __first.__ctz_ == 0;
51846035553Spatrick        // do middle words
51946035553Spatrick        unsigned __clz_r = __bits_per_word - __result.__ctz_;
52046035553Spatrick        __storage_type __m = ~__storage_type(0) << __result.__ctz_;
52146035553Spatrick        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
52246035553Spatrick        {
52346035553Spatrick            __storage_type __b = *__first.__seg_;
52446035553Spatrick            *__result.__seg_ &= ~__m;
52546035553Spatrick            *__result.__seg_ |= __b << __result.__ctz_;
52646035553Spatrick            ++__result.__seg_;
52746035553Spatrick            *__result.__seg_ &= __m;
52846035553Spatrick            *__result.__seg_ |= __b >> __clz_r;
52946035553Spatrick        }
53046035553Spatrick        // do last word
53146035553Spatrick        if (__n > 0)
53246035553Spatrick        {
53346035553Spatrick            __m = ~__storage_type(0) >> (__bits_per_word - __n);
53446035553Spatrick            __storage_type __b = *__first.__seg_ & __m;
53546035553Spatrick            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
53646035553Spatrick            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
53746035553Spatrick            *__result.__seg_ &= ~__m;
53846035553Spatrick            *__result.__seg_ |= __b << __result.__ctz_;
53946035553Spatrick            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
54046035553Spatrick            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
54146035553Spatrick            __n -= __dn;
54246035553Spatrick            if (__n > 0)
54346035553Spatrick            {
54446035553Spatrick                __m = ~__storage_type(0) >> (__bits_per_word - __n);
54546035553Spatrick                *__result.__seg_ &= ~__m;
54646035553Spatrick                *__result.__seg_ |= __b >> __dn;
54746035553Spatrick                __result.__ctz_ = static_cast<unsigned>(__n);
54846035553Spatrick            }
54946035553Spatrick        }
55046035553Spatrick    }
55146035553Spatrick    return __result;
55246035553Spatrick}
55346035553Spatrick
55446035553Spatricktemplate <class _Cp, bool _IsConst>
555*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
55646035553Spatrick__bit_iterator<_Cp, false>
55746035553Spatrickcopy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
55846035553Spatrick{
55946035553Spatrick    if (__first.__ctz_ == __result.__ctz_)
56076d0caaeSpatrick        return _VSTD::__copy_aligned(__first, __last, __result);
56176d0caaeSpatrick    return _VSTD::__copy_unaligned(__first, __last, __result);
56246035553Spatrick}
56346035553Spatrick
56446035553Spatrick// copy_backward
56546035553Spatrick
56646035553Spatricktemplate <class _Cp, bool _IsConst>
567*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
56846035553Spatrick__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
56946035553Spatrick                                                     __bit_iterator<_Cp, false> __result)
57046035553Spatrick{
57146035553Spatrick    typedef __bit_iterator<_Cp, _IsConst> _In;
57246035553Spatrick    typedef  typename _In::difference_type difference_type;
57346035553Spatrick    typedef typename _In::__storage_type __storage_type;
57446035553Spatrick    const int __bits_per_word = _In::__bits_per_word;
57546035553Spatrick    difference_type __n = __last - __first;
57646035553Spatrick    if (__n > 0)
57746035553Spatrick    {
57846035553Spatrick        // do first word
57946035553Spatrick        if (__last.__ctz_ != 0)
58046035553Spatrick        {
58146035553Spatrick            difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
58246035553Spatrick            __n -= __dn;
58346035553Spatrick            unsigned __clz = __bits_per_word - __last.__ctz_;
58446035553Spatrick            __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
58546035553Spatrick            __storage_type __b = *__last.__seg_ & __m;
58646035553Spatrick            *__result.__seg_ &= ~__m;
58746035553Spatrick            *__result.__seg_ |= __b;
58846035553Spatrick            __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
58946035553Spatrick                                                       __result.__ctz_)  % __bits_per_word);
59046035553Spatrick            // __last.__ctz_ = 0
59146035553Spatrick         }
59246035553Spatrick        // __last.__ctz_ == 0 || __n == 0
59346035553Spatrick        // __result.__ctz_ == 0 || __n == 0
59446035553Spatrick        // do middle words
59546035553Spatrick        __storage_type __nw = __n / __bits_per_word;
59646035553Spatrick        __result.__seg_ -= __nw;
59746035553Spatrick        __last.__seg_ -= __nw;
598*4bdff4beSrobert        std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_));
59946035553Spatrick        __n -= __nw * __bits_per_word;
60046035553Spatrick        // do last word
60146035553Spatrick        if (__n > 0)
60246035553Spatrick        {
60346035553Spatrick            __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
60446035553Spatrick            __storage_type __b = *--__last.__seg_ & __m;
60546035553Spatrick            *--__result.__seg_ &= ~__m;
60646035553Spatrick            *__result.__seg_ |= __b;
60746035553Spatrick            __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
60846035553Spatrick        }
60946035553Spatrick    }
61046035553Spatrick    return __result;
61146035553Spatrick}
61246035553Spatrick
61346035553Spatricktemplate <class _Cp, bool _IsConst>
614*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
61546035553Spatrick__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
61646035553Spatrick                                                       __bit_iterator<_Cp, false> __result)
61746035553Spatrick{
61846035553Spatrick    typedef __bit_iterator<_Cp, _IsConst> _In;
61946035553Spatrick    typedef  typename _In::difference_type difference_type;
62046035553Spatrick    typedef typename _In::__storage_type __storage_type;
62146035553Spatrick    const int __bits_per_word = _In::__bits_per_word;
62246035553Spatrick    difference_type __n = __last - __first;
62346035553Spatrick    if (__n > 0)
62446035553Spatrick    {
62546035553Spatrick        // do first word
62646035553Spatrick        if (__last.__ctz_ != 0)
62746035553Spatrick        {
62846035553Spatrick            difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
62946035553Spatrick            __n -= __dn;
63046035553Spatrick            unsigned __clz_l = __bits_per_word - __last.__ctz_;
63146035553Spatrick            __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
63246035553Spatrick            __storage_type __b = *__last.__seg_ & __m;
63346035553Spatrick            unsigned __clz_r = __bits_per_word - __result.__ctz_;
63446035553Spatrick            __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_));
63546035553Spatrick            if (__ddn > 0)
63646035553Spatrick            {
63746035553Spatrick                __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
63846035553Spatrick                *__result.__seg_ &= ~__m;
63946035553Spatrick                if (__result.__ctz_ > __last.__ctz_)
64046035553Spatrick                    *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
64146035553Spatrick                else
64246035553Spatrick                    *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
64346035553Spatrick                __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) +
64446035553Spatrick                                                         __result.__ctz_)  % __bits_per_word);
64546035553Spatrick                __dn -= __ddn;
64646035553Spatrick            }
64746035553Spatrick            if (__dn > 0)
64846035553Spatrick            {
64946035553Spatrick                // __result.__ctz_ == 0
65046035553Spatrick                --__result.__seg_;
65146035553Spatrick                __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
65246035553Spatrick                __m = ~__storage_type(0) << __result.__ctz_;
65346035553Spatrick                *__result.__seg_ &= ~__m;
65446035553Spatrick                __last.__ctz_ -= __dn + __ddn;
65546035553Spatrick                *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
65646035553Spatrick            }
65746035553Spatrick            // __last.__ctz_ = 0
65846035553Spatrick         }
65946035553Spatrick        // __last.__ctz_ == 0 || __n == 0
66046035553Spatrick        // __result.__ctz_ != 0 || __n == 0
66146035553Spatrick        // do middle words
66246035553Spatrick        unsigned __clz_r = __bits_per_word - __result.__ctz_;
66346035553Spatrick        __storage_type __m = ~__storage_type(0) >> __clz_r;
66446035553Spatrick        for (; __n >= __bits_per_word; __n -= __bits_per_word)
66546035553Spatrick        {
66646035553Spatrick            __storage_type __b = *--__last.__seg_;
66746035553Spatrick            *__result.__seg_ &= ~__m;
66846035553Spatrick            *__result.__seg_ |= __b >> __clz_r;
66946035553Spatrick            *--__result.__seg_ &= __m;
67046035553Spatrick            *__result.__seg_ |= __b << __result.__ctz_;
67146035553Spatrick        }
67246035553Spatrick        // do last word
67346035553Spatrick        if (__n > 0)
67446035553Spatrick        {
67546035553Spatrick            __m = ~__storage_type(0) << (__bits_per_word - __n);
67646035553Spatrick            __storage_type __b = *--__last.__seg_ & __m;
67746035553Spatrick            __clz_r = __bits_per_word - __result.__ctz_;
67846035553Spatrick            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_));
67946035553Spatrick            __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
68046035553Spatrick            *__result.__seg_ &= ~__m;
68146035553Spatrick            *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
68246035553Spatrick            __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
68346035553Spatrick                                                     __result.__ctz_)  % __bits_per_word);
68446035553Spatrick            __n -= __dn;
68546035553Spatrick            if (__n > 0)
68646035553Spatrick            {
68746035553Spatrick                // __result.__ctz_ == 0
68846035553Spatrick                --__result.__seg_;
68946035553Spatrick                __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
69046035553Spatrick                __m = ~__storage_type(0) << __result.__ctz_;
69146035553Spatrick                *__result.__seg_ &= ~__m;
69246035553Spatrick                *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
69346035553Spatrick            }
69446035553Spatrick        }
69546035553Spatrick    }
69646035553Spatrick    return __result;
69746035553Spatrick}
69846035553Spatrick
69946035553Spatricktemplate <class _Cp, bool _IsConst>
700*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
70146035553Spatrick__bit_iterator<_Cp, false>
70246035553Spatrickcopy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
70346035553Spatrick{
70446035553Spatrick    if (__last.__ctz_ == __result.__ctz_)
70576d0caaeSpatrick        return _VSTD::__copy_backward_aligned(__first, __last, __result);
70676d0caaeSpatrick    return _VSTD::__copy_backward_unaligned(__first, __last, __result);
70746035553Spatrick}
70846035553Spatrick
70946035553Spatrick// move
71046035553Spatrick
71146035553Spatricktemplate <class _Cp, bool _IsConst>
71246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
71346035553Spatrick__bit_iterator<_Cp, false>
71446035553Spatrickmove(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
71546035553Spatrick{
71646035553Spatrick    return _VSTD::copy(__first, __last, __result);
71746035553Spatrick}
71846035553Spatrick
71946035553Spatrick// move_backward
72046035553Spatrick
72146035553Spatricktemplate <class _Cp, bool _IsConst>
72246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
72346035553Spatrick__bit_iterator<_Cp, false>
72446035553Spatrickmove_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
72546035553Spatrick{
72646035553Spatrick    return _VSTD::copy_backward(__first, __last, __result);
72746035553Spatrick}
72846035553Spatrick
72946035553Spatrick// swap_ranges
73046035553Spatrick
73146035553Spatricktemplate <class __C1, class __C2>
732*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false>
73346035553Spatrick__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
73446035553Spatrick                      __bit_iterator<__C2, false> __result)
73546035553Spatrick{
73646035553Spatrick    typedef __bit_iterator<__C1, false> _I1;
73746035553Spatrick    typedef  typename _I1::difference_type difference_type;
73846035553Spatrick    typedef typename _I1::__storage_type __storage_type;
73946035553Spatrick    const int __bits_per_word = _I1::__bits_per_word;
74046035553Spatrick    difference_type __n = __last - __first;
74146035553Spatrick    if (__n > 0)
74246035553Spatrick    {
74346035553Spatrick        // do first word
74446035553Spatrick        if (__first.__ctz_ != 0)
74546035553Spatrick        {
74646035553Spatrick            unsigned __clz = __bits_per_word - __first.__ctz_;
74746035553Spatrick            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
74846035553Spatrick            __n -= __dn;
74946035553Spatrick            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
75046035553Spatrick            __storage_type __b1 = *__first.__seg_ & __m;
75146035553Spatrick            *__first.__seg_ &= ~__m;
75246035553Spatrick            __storage_type __b2 = *__result.__seg_ & __m;
75346035553Spatrick            *__result.__seg_ &= ~__m;
75446035553Spatrick            *__result.__seg_ |= __b1;
75546035553Spatrick            *__first.__seg_  |= __b2;
75646035553Spatrick            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
75746035553Spatrick            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
75846035553Spatrick            ++__first.__seg_;
75946035553Spatrick            // __first.__ctz_ = 0;
76046035553Spatrick        }
76146035553Spatrick        // __first.__ctz_ == 0;
76246035553Spatrick        // do middle words
76346035553Spatrick        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
76446035553Spatrick            swap(*__first.__seg_, *__result.__seg_);
76546035553Spatrick        // do last word
76646035553Spatrick        if (__n > 0)
76746035553Spatrick        {
76846035553Spatrick            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
76946035553Spatrick            __storage_type __b1 = *__first.__seg_ & __m;
77046035553Spatrick            *__first.__seg_ &= ~__m;
77146035553Spatrick            __storage_type __b2 = *__result.__seg_ & __m;
77246035553Spatrick            *__result.__seg_ &= ~__m;
77346035553Spatrick            *__result.__seg_ |= __b1;
77446035553Spatrick            *__first.__seg_  |= __b2;
77546035553Spatrick            __result.__ctz_ = static_cast<unsigned>(__n);
77646035553Spatrick        }
77746035553Spatrick    }
77846035553Spatrick    return __result;
77946035553Spatrick}
78046035553Spatrick
78146035553Spatricktemplate <class __C1, class __C2>
782*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false>
78346035553Spatrick__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
78446035553Spatrick                        __bit_iterator<__C2, false> __result)
78546035553Spatrick{
78646035553Spatrick    typedef __bit_iterator<__C1, false> _I1;
78746035553Spatrick    typedef  typename _I1::difference_type difference_type;
78846035553Spatrick    typedef typename _I1::__storage_type __storage_type;
78946035553Spatrick    const int __bits_per_word = _I1::__bits_per_word;
79046035553Spatrick    difference_type __n = __last - __first;
79146035553Spatrick    if (__n > 0)
79246035553Spatrick    {
79346035553Spatrick        // do first word
79446035553Spatrick        if (__first.__ctz_ != 0)
79546035553Spatrick        {
79646035553Spatrick            unsigned __clz_f = __bits_per_word - __first.__ctz_;
79746035553Spatrick            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
79846035553Spatrick            __n -= __dn;
79946035553Spatrick            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
80046035553Spatrick            __storage_type __b1 = *__first.__seg_ & __m;
80146035553Spatrick            *__first.__seg_ &= ~__m;
80246035553Spatrick            unsigned __clz_r = __bits_per_word - __result.__ctz_;
80346035553Spatrick            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
80446035553Spatrick            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
80546035553Spatrick            __storage_type __b2 = *__result.__seg_ & __m;
80646035553Spatrick            *__result.__seg_ &= ~__m;
80746035553Spatrick            if (__result.__ctz_ > __first.__ctz_)
80846035553Spatrick            {
80946035553Spatrick                unsigned __s = __result.__ctz_ - __first.__ctz_;
81046035553Spatrick                *__result.__seg_ |= __b1 << __s;
81146035553Spatrick                *__first.__seg_  |= __b2 >> __s;
81246035553Spatrick            }
81346035553Spatrick            else
81446035553Spatrick            {
81546035553Spatrick                unsigned __s = __first.__ctz_ - __result.__ctz_;
81646035553Spatrick                *__result.__seg_ |= __b1 >> __s;
81746035553Spatrick                *__first.__seg_  |= __b2 << __s;
81846035553Spatrick            }
81946035553Spatrick            __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
82046035553Spatrick            __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_)  % __bits_per_word);
82146035553Spatrick            __dn -= __ddn;
82246035553Spatrick            if (__dn > 0)
82346035553Spatrick            {
82446035553Spatrick                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
82546035553Spatrick                __b2 = *__result.__seg_ & __m;
82646035553Spatrick                *__result.__seg_ &= ~__m;
82746035553Spatrick                unsigned __s = __first.__ctz_ + __ddn;
82846035553Spatrick                *__result.__seg_ |= __b1 >> __s;
82946035553Spatrick                *__first.__seg_  |= __b2 << __s;
83046035553Spatrick                __result.__ctz_ = static_cast<unsigned>(__dn);
83146035553Spatrick            }
83246035553Spatrick            ++__first.__seg_;
83346035553Spatrick            // __first.__ctz_ = 0;
83446035553Spatrick        }
83546035553Spatrick        // __first.__ctz_ == 0;
83646035553Spatrick        // do middle words
83746035553Spatrick        __storage_type __m = ~__storage_type(0) << __result.__ctz_;
83846035553Spatrick        unsigned __clz_r = __bits_per_word - __result.__ctz_;
83946035553Spatrick        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
84046035553Spatrick        {
84146035553Spatrick            __storage_type __b1 = *__first.__seg_;
84246035553Spatrick            __storage_type __b2 = *__result.__seg_ & __m;
84346035553Spatrick            *__result.__seg_ &= ~__m;
84446035553Spatrick            *__result.__seg_ |= __b1 << __result.__ctz_;
84546035553Spatrick            *__first.__seg_  = __b2 >> __result.__ctz_;
84646035553Spatrick            ++__result.__seg_;
84746035553Spatrick            __b2 = *__result.__seg_ & ~__m;
84846035553Spatrick            *__result.__seg_ &= __m;
84946035553Spatrick            *__result.__seg_ |= __b1 >> __clz_r;
85046035553Spatrick            *__first.__seg_  |= __b2 << __clz_r;
85146035553Spatrick        }
85246035553Spatrick        // do last word
85346035553Spatrick        if (__n > 0)
85446035553Spatrick        {
85546035553Spatrick            __m = ~__storage_type(0) >> (__bits_per_word - __n);
85646035553Spatrick            __storage_type __b1 = *__first.__seg_ & __m;
85746035553Spatrick            *__first.__seg_ &= ~__m;
85846035553Spatrick            __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r);
85946035553Spatrick            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
86046035553Spatrick            __storage_type __b2 = *__result.__seg_ & __m;
86146035553Spatrick            *__result.__seg_ &= ~__m;
86246035553Spatrick            *__result.__seg_ |= __b1 << __result.__ctz_;
86346035553Spatrick            *__first.__seg_  |= __b2 >> __result.__ctz_;
86446035553Spatrick            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
86546035553Spatrick            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
86646035553Spatrick            __n -= __dn;
86746035553Spatrick            if (__n > 0)
86846035553Spatrick            {
86946035553Spatrick                __m = ~__storage_type(0) >> (__bits_per_word - __n);
87046035553Spatrick                __b2 = *__result.__seg_ & __m;
87146035553Spatrick                *__result.__seg_ &= ~__m;
87246035553Spatrick                *__result.__seg_ |= __b1 >> __dn;
87346035553Spatrick                *__first.__seg_  |= __b2 << __dn;
87446035553Spatrick                __result.__ctz_ = static_cast<unsigned>(__n);
87546035553Spatrick            }
87646035553Spatrick        }
87746035553Spatrick    }
87846035553Spatrick    return __result;
87946035553Spatrick}
88046035553Spatrick
88146035553Spatricktemplate <class __C1, class __C2>
88246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
88346035553Spatrick__bit_iterator<__C2, false>
88446035553Spatrickswap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
88546035553Spatrick            __bit_iterator<__C2, false> __first2)
88646035553Spatrick{
88746035553Spatrick    if (__first1.__ctz_ == __first2.__ctz_)
88876d0caaeSpatrick        return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2);
88976d0caaeSpatrick    return _VSTD::__swap_ranges_unaligned(__first1, __last1, __first2);
89046035553Spatrick}
89146035553Spatrick
89246035553Spatrick// rotate
89346035553Spatrick
89446035553Spatricktemplate <class _Cp>
89546035553Spatrickstruct __bit_array
89646035553Spatrick{
89746035553Spatrick    typedef typename _Cp::difference_type difference_type;
89846035553Spatrick    typedef typename _Cp::__storage_type  __storage_type;
89946035553Spatrick    typedef typename _Cp::__storage_pointer __storage_pointer;
90046035553Spatrick    typedef typename _Cp::iterator        iterator;
90146035553Spatrick    static const unsigned __bits_per_word = _Cp::__bits_per_word;
90246035553Spatrick    static const unsigned _Np = 4;
90346035553Spatrick
90446035553Spatrick    difference_type __size_;
90546035553Spatrick    __storage_type __word_[_Np];
90646035553Spatrick
907*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity()
90846035553Spatrick        {return static_cast<difference_type>(_Np * __bits_per_word);}
909*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) {
910*4bdff4beSrobert        if (__libcpp_is_constant_evaluated()) {
911*4bdff4beSrobert            for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i)
912*4bdff4beSrobert                std::__construct_at(__word_ + __i, 0);
913*4bdff4beSrobert        }
914*4bdff4beSrobert    }
915*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin()
91646035553Spatrick    {
91746035553Spatrick        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
91846035553Spatrick    }
919*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end()
92046035553Spatrick    {
92146035553Spatrick        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
92246035553Spatrick                                                  static_cast<unsigned>(__size_ % __bits_per_word));
92346035553Spatrick    }
92446035553Spatrick};
92546035553Spatrick
92646035553Spatricktemplate <class _Cp>
927*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
92846035553Spatrickrotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)
92946035553Spatrick{
93046035553Spatrick    typedef __bit_iterator<_Cp, false> _I1;
93146035553Spatrick    typedef  typename _I1::difference_type difference_type;
93246035553Spatrick    difference_type __d1 = __middle - __first;
93346035553Spatrick    difference_type __d2 = __last - __middle;
93446035553Spatrick    _I1 __r = __first + __d2;
93546035553Spatrick    while (__d1 != 0 && __d2 != 0)
93646035553Spatrick    {
93746035553Spatrick        if (__d1 <= __d2)
93846035553Spatrick        {
93946035553Spatrick            if (__d1 <= __bit_array<_Cp>::capacity())
94046035553Spatrick            {
94146035553Spatrick                __bit_array<_Cp> __b(__d1);
94246035553Spatrick                _VSTD::copy(__first, __middle, __b.begin());
94346035553Spatrick                _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first));
94446035553Spatrick                break;
94546035553Spatrick            }
94646035553Spatrick            else
94746035553Spatrick            {
94846035553Spatrick                __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle);
94946035553Spatrick                __first = __middle;
95046035553Spatrick                __middle = __mp;
95146035553Spatrick                __d2 -= __d1;
95246035553Spatrick            }
95346035553Spatrick        }
95446035553Spatrick        else
95546035553Spatrick        {
95646035553Spatrick            if (__d2 <= __bit_array<_Cp>::capacity())
95746035553Spatrick            {
95846035553Spatrick                __bit_array<_Cp> __b(__d2);
95946035553Spatrick                _VSTD::copy(__middle, __last, __b.begin());
96046035553Spatrick                _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last));
96146035553Spatrick                break;
96246035553Spatrick            }
96346035553Spatrick            else
96446035553Spatrick            {
96546035553Spatrick                __bit_iterator<_Cp, false> __mp = __first + __d2;
96646035553Spatrick                _VSTD::swap_ranges(__first, __mp, __middle);
96746035553Spatrick                __first = __mp;
96846035553Spatrick                __d1 -= __d2;
96946035553Spatrick            }
97046035553Spatrick        }
97146035553Spatrick    }
97246035553Spatrick    return __r;
97346035553Spatrick}
97446035553Spatrick
97546035553Spatrick// equal
97646035553Spatrick
97746035553Spatricktemplate <class _Cp, bool _IC1, bool _IC2>
978*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
97946035553Spatrick__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
98046035553Spatrick                  __bit_iterator<_Cp, _IC2> __first2)
98146035553Spatrick{
98246035553Spatrick    typedef __bit_iterator<_Cp, _IC1> _It;
98346035553Spatrick    typedef  typename _It::difference_type difference_type;
98446035553Spatrick    typedef typename _It::__storage_type __storage_type;
985*4bdff4beSrobert    const int __bits_per_word = _It::__bits_per_word;
98646035553Spatrick    difference_type __n = __last1 - __first1;
98746035553Spatrick    if (__n > 0)
98846035553Spatrick    {
98946035553Spatrick        // do first word
99046035553Spatrick        if (__first1.__ctz_ != 0)
99146035553Spatrick        {
99246035553Spatrick            unsigned __clz_f = __bits_per_word - __first1.__ctz_;
99346035553Spatrick            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
99446035553Spatrick            __n -= __dn;
99546035553Spatrick            __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
99646035553Spatrick            __storage_type __b = *__first1.__seg_ & __m;
99746035553Spatrick            unsigned __clz_r = __bits_per_word - __first2.__ctz_;
99846035553Spatrick            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
99946035553Spatrick            __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
100046035553Spatrick            if (__first2.__ctz_ > __first1.__ctz_)
100146035553Spatrick            {
100246035553Spatrick                if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
100346035553Spatrick                    return false;
100446035553Spatrick            }
100546035553Spatrick            else
100646035553Spatrick            {
100746035553Spatrick                if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
100846035553Spatrick                    return false;
100946035553Spatrick            }
101046035553Spatrick            __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
101146035553Spatrick            __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_)  % __bits_per_word);
101246035553Spatrick            __dn -= __ddn;
101346035553Spatrick            if (__dn > 0)
101446035553Spatrick            {
101546035553Spatrick                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
101646035553Spatrick                if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
101746035553Spatrick                    return false;
101846035553Spatrick                __first2.__ctz_ = static_cast<unsigned>(__dn);
101946035553Spatrick            }
102046035553Spatrick            ++__first1.__seg_;
102146035553Spatrick            // __first1.__ctz_ = 0;
102246035553Spatrick        }
102346035553Spatrick        // __first1.__ctz_ == 0;
102446035553Spatrick        // do middle words
102546035553Spatrick        unsigned __clz_r = __bits_per_word - __first2.__ctz_;
102646035553Spatrick        __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
102746035553Spatrick        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_)
102846035553Spatrick        {
102946035553Spatrick            __storage_type __b = *__first1.__seg_;
103046035553Spatrick            if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
103146035553Spatrick                return false;
103246035553Spatrick            ++__first2.__seg_;
103346035553Spatrick            if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
103446035553Spatrick                return false;
103546035553Spatrick        }
103646035553Spatrick        // do last word
103746035553Spatrick        if (__n > 0)
103846035553Spatrick        {
103946035553Spatrick            __m = ~__storage_type(0) >> (__bits_per_word - __n);
104046035553Spatrick            __storage_type __b = *__first1.__seg_ & __m;
104146035553Spatrick            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
104246035553Spatrick            __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
104346035553Spatrick            if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
104446035553Spatrick                return false;
104546035553Spatrick            __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
104646035553Spatrick            __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_)  % __bits_per_word);
104746035553Spatrick            __n -= __dn;
104846035553Spatrick            if (__n > 0)
104946035553Spatrick            {
105046035553Spatrick                __m = ~__storage_type(0) >> (__bits_per_word - __n);
105146035553Spatrick                if ((*__first2.__seg_ & __m) != (__b >> __dn))
105246035553Spatrick                    return false;
105346035553Spatrick            }
105446035553Spatrick        }
105546035553Spatrick    }
105646035553Spatrick    return true;
105746035553Spatrick}
105846035553Spatrick
105946035553Spatricktemplate <class _Cp, bool _IC1, bool _IC2>
1060*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool
106146035553Spatrick__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
106246035553Spatrick                __bit_iterator<_Cp, _IC2> __first2)
106346035553Spatrick{
106446035553Spatrick    typedef __bit_iterator<_Cp, _IC1> _It;
106546035553Spatrick    typedef  typename _It::difference_type difference_type;
106646035553Spatrick    typedef typename _It::__storage_type __storage_type;
1067*4bdff4beSrobert    const int __bits_per_word = _It::__bits_per_word;
106846035553Spatrick    difference_type __n = __last1 - __first1;
106946035553Spatrick    if (__n > 0)
107046035553Spatrick    {
107146035553Spatrick        // do first word
107246035553Spatrick        if (__first1.__ctz_ != 0)
107346035553Spatrick        {
107446035553Spatrick            unsigned __clz = __bits_per_word - __first1.__ctz_;
107546035553Spatrick            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
107646035553Spatrick            __n -= __dn;
107746035553Spatrick            __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
107846035553Spatrick            if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
107946035553Spatrick                return false;
108046035553Spatrick            ++__first2.__seg_;
108146035553Spatrick            ++__first1.__seg_;
108246035553Spatrick            // __first1.__ctz_ = 0;
108346035553Spatrick            // __first2.__ctz_ = 0;
108446035553Spatrick        }
108546035553Spatrick        // __first1.__ctz_ == 0;
108646035553Spatrick        // __first2.__ctz_ == 0;
108746035553Spatrick        // do middle words
108846035553Spatrick        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
108946035553Spatrick            if (*__first2.__seg_ != *__first1.__seg_)
109046035553Spatrick                return false;
109146035553Spatrick        // do last word
109246035553Spatrick        if (__n > 0)
109346035553Spatrick        {
109446035553Spatrick            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
109546035553Spatrick            if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
109646035553Spatrick                return false;
109746035553Spatrick        }
109846035553Spatrick    }
109946035553Spatrick    return true;
110046035553Spatrick}
110146035553Spatrick
110246035553Spatricktemplate <class _Cp, bool _IC1, bool _IC2>
1103*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
110446035553Spatrickbool
110546035553Spatrickequal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
110646035553Spatrick{
110746035553Spatrick    if (__first1.__ctz_ == __first2.__ctz_)
110876d0caaeSpatrick        return _VSTD::__equal_aligned(__first1, __last1, __first2);
110976d0caaeSpatrick    return _VSTD::__equal_unaligned(__first1, __last1, __first2);
111046035553Spatrick}
111146035553Spatrick
111246035553Spatricktemplate <class _Cp, bool _IsConst,
111346035553Spatrick          typename _Cp::__storage_type>
111446035553Spatrickclass __bit_iterator
111546035553Spatrick{
111646035553Spatrickpublic:
111746035553Spatrick    typedef typename _Cp::difference_type                                                          difference_type;
111846035553Spatrick    typedef bool                                                                                  value_type;
111946035553Spatrick    typedef __bit_iterator                                                                        pointer;
1120*4bdff4beSrobert#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
1121*4bdff4beSrobert    typedef __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> > reference;
1122*4bdff4beSrobert#else
1123*4bdff4beSrobert    using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >;
1124*4bdff4beSrobert#endif
112546035553Spatrick    typedef random_access_iterator_tag                                                            iterator_category;
112646035553Spatrick
112746035553Spatrickprivate:
112846035553Spatrick    typedef typename _Cp::__storage_type                                           __storage_type;
1129*4bdff4beSrobert    typedef __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>
1130*4bdff4beSrobert        __storage_pointer;
113146035553Spatrick    static const unsigned __bits_per_word = _Cp::__bits_per_word;
113246035553Spatrick
113346035553Spatrick    __storage_pointer __seg_;
113446035553Spatrick    unsigned          __ctz_;
113546035553Spatrick
113646035553Spatrickpublic:
1137*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT
113846035553Spatrick#if _LIBCPP_STD_VER > 11
113946035553Spatrick    : __seg_(nullptr), __ctz_(0)
114046035553Spatrick#endif
114146035553Spatrick    {}
114246035553Spatrick
114376d0caaeSpatrick    // When _IsConst=false, this is the copy constructor.
114476d0caaeSpatrick    // It is non-trivial. Making it trivial would break ABI.
114576d0caaeSpatrick    // When _IsConst=true, this is a converting constructor;
114676d0caaeSpatrick    // the copy and move constructors are implicitly generated
114776d0caaeSpatrick    // and trivial.
1148*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
114976d0caaeSpatrick    __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
115046035553Spatrick        : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
115146035553Spatrick
115276d0caaeSpatrick    // When _IsConst=false, we have a user-provided copy constructor,
115376d0caaeSpatrick    // so we must also provide a copy assignment operator because
115476d0caaeSpatrick    // the implicit generation of a defaulted one is deprecated.
115576d0caaeSpatrick    // When _IsConst=true, the assignment operators are
115676d0caaeSpatrick    // implicitly generated and trivial.
1157*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
115876d0caaeSpatrick    __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
115976d0caaeSpatrick        __seg_ = __it.__seg_;
116076d0caaeSpatrick        __ctz_ = __it.__ctz_;
116176d0caaeSpatrick        return *this;
116276d0caaeSpatrick    }
116346035553Spatrick
1164*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
1165*4bdff4beSrobert        return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >(
1166*4bdff4beSrobert            __seg_, __storage_type(1) << __ctz_);
1167*4bdff4beSrobert    }
116846035553Spatrick
1169*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++()
117046035553Spatrick    {
117146035553Spatrick        if (__ctz_ != __bits_per_word-1)
117246035553Spatrick            ++__ctz_;
117346035553Spatrick        else
117446035553Spatrick        {
117546035553Spatrick            __ctz_ = 0;
117646035553Spatrick            ++__seg_;
117746035553Spatrick        }
117846035553Spatrick        return *this;
117946035553Spatrick    }
118046035553Spatrick
1181*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int)
118246035553Spatrick    {
118346035553Spatrick        __bit_iterator __tmp = *this;
118446035553Spatrick        ++(*this);
118546035553Spatrick        return __tmp;
118646035553Spatrick    }
118746035553Spatrick
1188*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--()
118946035553Spatrick    {
119046035553Spatrick        if (__ctz_ != 0)
119146035553Spatrick            --__ctz_;
119246035553Spatrick        else
119346035553Spatrick        {
119446035553Spatrick            __ctz_ = __bits_per_word - 1;
119546035553Spatrick            --__seg_;
119646035553Spatrick        }
119746035553Spatrick        return *this;
119846035553Spatrick    }
119946035553Spatrick
1200*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int)
120146035553Spatrick    {
120246035553Spatrick        __bit_iterator __tmp = *this;
120346035553Spatrick        --(*this);
120446035553Spatrick        return __tmp;
120546035553Spatrick    }
120646035553Spatrick
1207*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n)
120846035553Spatrick    {
120946035553Spatrick        if (__n >= 0)
121046035553Spatrick            __seg_ += (__n + __ctz_) / __bits_per_word;
121146035553Spatrick        else
121246035553Spatrick            __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1)
121346035553Spatrick                    / static_cast<difference_type>(__bits_per_word);
121446035553Spatrick        __n &= (__bits_per_word - 1);
121546035553Spatrick        __ctz_ = static_cast<unsigned>((__n + __ctz_)  % __bits_per_word);
121646035553Spatrick        return *this;
121746035553Spatrick    }
121846035553Spatrick
1219*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n)
122046035553Spatrick    {
122146035553Spatrick        return *this += -__n;
122246035553Spatrick    }
122346035553Spatrick
1224*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const
122546035553Spatrick    {
122646035553Spatrick        __bit_iterator __t(*this);
122746035553Spatrick        __t += __n;
122846035553Spatrick        return __t;
122946035553Spatrick    }
123046035553Spatrick
1231*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const
123246035553Spatrick    {
123346035553Spatrick        __bit_iterator __t(*this);
123446035553Spatrick        __t -= __n;
123546035553Spatrick        return __t;
123646035553Spatrick    }
123746035553Spatrick
1238*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
123946035553Spatrick    friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}
124046035553Spatrick
1241*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
124246035553Spatrick    friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)
124346035553Spatrick        {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}
124446035553Spatrick
1245*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const {return *(*this + __n);}
124646035553Spatrick
1247*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
124846035553Spatrick        {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}
124946035553Spatrick
1250*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
125146035553Spatrick        {return !(__x == __y);}
125246035553Spatrick
1253*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
125446035553Spatrick        {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}
125546035553Spatrick
1256*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
125746035553Spatrick        {return __y < __x;}
125846035553Spatrick
1259*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)
126046035553Spatrick        {return !(__y < __x);}
126146035553Spatrick
1262*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)
126346035553Spatrick        {return !(__x < __y);}
126446035553Spatrick
126546035553Spatrickprivate:
1266*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
1267*4bdff4beSrobert    explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
126846035553Spatrick        : __seg_(__s), __ctz_(__ctz) {}
126946035553Spatrick
127046035553Spatrick    friend typename _Cp::__self;
127146035553Spatrick
127246035553Spatrick    friend class __bit_reference<_Cp>;
127346035553Spatrick    friend class __bit_const_reference<_Cp>;
127446035553Spatrick    friend class __bit_iterator<_Cp, true>;
127546035553Spatrick    template <class _Dp> friend struct __bit_array;
1276*4bdff4beSrobert    template <class _Dp>
1277*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1278*4bdff4beSrobert    friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1279*4bdff4beSrobert
1280*4bdff4beSrobert    template <class _Dp>
1281*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1282*4bdff4beSrobert    friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1283*4bdff4beSrobert
1284*4bdff4beSrobert    template <class _Dp, bool _IC>
1285*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1286*4bdff4beSrobert    friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
128746035553Spatrick                                                     __bit_iterator<_Dp, _IC> __last,
128846035553Spatrick                                                     __bit_iterator<_Dp, false> __result);
1289*4bdff4beSrobert    template <class _Dp, bool _IC>
1290*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1291*4bdff4beSrobert    friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,
129246035553Spatrick                                                       __bit_iterator<_Dp, _IC> __last,
129346035553Spatrick                                                       __bit_iterator<_Dp, false> __result);
1294*4bdff4beSrobert    template <class _Dp, bool _IC>
1295*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1296*4bdff4beSrobert    friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,
129746035553Spatrick                                           __bit_iterator<_Dp, _IC> __last,
129846035553Spatrick                                           __bit_iterator<_Dp, false> __result);
1299*4bdff4beSrobert    template <class _Dp, bool _IC>
1300*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1301*4bdff4beSrobert    friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first,
130246035553Spatrick                                                              __bit_iterator<_Dp, _IC> __last,
130346035553Spatrick                                                              __bit_iterator<_Dp, false> __result);
1304*4bdff4beSrobert    template <class _Dp, bool _IC>
1305*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1306*4bdff4beSrobert    friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first,
130746035553Spatrick                                                                __bit_iterator<_Dp, _IC> __last,
130846035553Spatrick                                                                __bit_iterator<_Dp, false> __result);
1309*4bdff4beSrobert    template <class _Dp, bool _IC>
1310*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1311*4bdff4beSrobert    friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
131246035553Spatrick                                                    __bit_iterator<_Dp, _IC> __last,
131346035553Spatrick                                                    __bit_iterator<_Dp, false> __result);
131446035553Spatrick    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
131546035553Spatrick                                                                                           __bit_iterator<__C1, false>,
131646035553Spatrick                                                                                           __bit_iterator<__C2, false>);
131746035553Spatrick    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,
131846035553Spatrick                                                                                             __bit_iterator<__C1, false>,
131946035553Spatrick                                                                                             __bit_iterator<__C2, false>);
132046035553Spatrick    template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
132146035553Spatrick                                                                                 __bit_iterator<__C1, false>,
132246035553Spatrick                                                                                 __bit_iterator<__C2, false>);
1323*4bdff4beSrobert    template <class _Dp>
1324*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1325*4bdff4beSrobert    friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
132646035553Spatrick                                             __bit_iterator<_Dp, false>,
132746035553Spatrick                                             __bit_iterator<_Dp, false>);
1328*4bdff4beSrobert    template <class _Dp, bool _IC1, bool _IC2>
1329*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1330*4bdff4beSrobert    friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
133146035553Spatrick                                __bit_iterator<_Dp, _IC1>,
133246035553Spatrick                                __bit_iterator<_Dp, _IC2>);
1333*4bdff4beSrobert    template <class _Dp, bool _IC1, bool _IC2>
1334*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1335*4bdff4beSrobert    friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
133646035553Spatrick                                  __bit_iterator<_Dp, _IC1>,
133746035553Spatrick                                  __bit_iterator<_Dp, _IC2>);
1338*4bdff4beSrobert    template <class _Dp, bool _IC1, bool _IC2>
1339*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1340*4bdff4beSrobert    friend bool equal(__bit_iterator<_Dp, _IC1>,
134146035553Spatrick                      __bit_iterator<_Dp, _IC1>,
134246035553Spatrick                      __bit_iterator<_Dp, _IC2>);
1343*4bdff4beSrobert    template <class _Dp, bool _IC>
1344*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1345*4bdff4beSrobert    friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1346*4bdff4beSrobert    template <class _Dp, bool _IC>
1347*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX20
1348*4bdff4beSrobert    friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
134946035553Spatrick    template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1350*4bdff4beSrobert    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
135146035553Spatrick                   __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
135246035553Spatrick    template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
135346035553Spatrick                   __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
135446035553Spatrick};
135546035553Spatrick
135646035553Spatrick_LIBCPP_END_NAMESPACE_STD
135746035553Spatrick
135846035553Spatrick_LIBCPP_POP_MACROS
135946035553Spatrick
136046035553Spatrick#endif // _LIBCPP___BIT_REFERENCE
1361