xref: /freebsd/contrib/llvm-project/libcxx/include/__cxx03/__bit_reference (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric// -*- C++ -*-
2*700637cbSDimitry Andric//===----------------------------------------------------------------------===//
3*700637cbSDimitry Andric//
4*700637cbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*700637cbSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*700637cbSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*700637cbSDimitry Andric//
8*700637cbSDimitry Andric//===----------------------------------------------------------------------===//
9*700637cbSDimitry Andric
10*700637cbSDimitry Andric#ifndef _LIBCPP___CXX03___BIT_REFERENCE
11*700637cbSDimitry Andric#define _LIBCPP___CXX03___BIT_REFERENCE
12*700637cbSDimitry Andric
13*700637cbSDimitry Andric#include <__cxx03/__algorithm/copy_n.h>
14*700637cbSDimitry Andric#include <__cxx03/__algorithm/fill_n.h>
15*700637cbSDimitry Andric#include <__cxx03/__algorithm/min.h>
16*700637cbSDimitry Andric#include <__cxx03/__bit/countr.h>
17*700637cbSDimitry Andric#include <__cxx03/__bit/invert_if.h>
18*700637cbSDimitry Andric#include <__cxx03/__bit/popcount.h>
19*700637cbSDimitry Andric#include <__cxx03/__config>
20*700637cbSDimitry Andric#include <__cxx03/__fwd/bit_reference.h>
21*700637cbSDimitry Andric#include <__cxx03/__iterator/iterator_traits.h>
22*700637cbSDimitry Andric#include <__cxx03/__memory/construct_at.h>
23*700637cbSDimitry Andric#include <__cxx03/__memory/pointer_traits.h>
24*700637cbSDimitry Andric#include <__cxx03/__type_traits/conditional.h>
25*700637cbSDimitry Andric#include <__cxx03/__utility/swap.h>
26*700637cbSDimitry Andric#include <__cxx03/cstring>
27*700637cbSDimitry Andric
28*700637cbSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29*700637cbSDimitry Andric#  pragma GCC system_header
30*700637cbSDimitry Andric#endif
31*700637cbSDimitry Andric
32*700637cbSDimitry Andric_LIBCPP_PUSH_MACROS
33*700637cbSDimitry Andric#include <__cxx03/__undef_macros>
34*700637cbSDimitry Andric
35*700637cbSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
36*700637cbSDimitry Andric
37*700637cbSDimitry Andrictemplate <class _Cp>
38*700637cbSDimitry Andricclass __bit_const_reference;
39*700637cbSDimitry Andric
40*700637cbSDimitry Andrictemplate <class _Tp>
41*700637cbSDimitry Andricstruct __has_storage_type {
42*700637cbSDimitry Andric  static const bool value = false;
43*700637cbSDimitry Andric};
44*700637cbSDimitry Andric
45*700637cbSDimitry Andrictemplate <class _Cp, bool = __has_storage_type<_Cp>::value>
46*700637cbSDimitry Andricclass __bit_reference {
47*700637cbSDimitry Andric  using __storage_type    = typename _Cp::__storage_type;
48*700637cbSDimitry Andric  using __storage_pointer = typename _Cp::__storage_pointer;
49*700637cbSDimitry Andric
50*700637cbSDimitry Andric  __storage_pointer __seg_;
51*700637cbSDimitry Andric  __storage_type __mask_;
52*700637cbSDimitry Andric
53*700637cbSDimitry Andric  friend typename _Cp::__self;
54*700637cbSDimitry Andric
55*700637cbSDimitry Andric  friend class __bit_const_reference<_Cp>;
56*700637cbSDimitry Andric  friend class __bit_iterator<_Cp, false>;
57*700637cbSDimitry Andric
58*700637cbSDimitry Andricpublic:
59*700637cbSDimitry Andric  using __container = typename _Cp::__self;
60*700637cbSDimitry Andric
61*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_reference(const __bit_reference&) = default;
62*700637cbSDimitry Andric
63*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { return static_cast<bool>(*__seg_ & __mask_); }
64*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool operator~() const _NOEXCEPT { return !static_cast<bool>(*this); }
65*700637cbSDimitry Andric
66*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_reference& operator=(bool __x) _NOEXCEPT {
67*700637cbSDimitry Andric    if (__x)
68*700637cbSDimitry Andric      *__seg_ |= __mask_;
69*700637cbSDimitry Andric    else
70*700637cbSDimitry Andric      *__seg_ &= ~__mask_;
71*700637cbSDimitry Andric    return *this;
72*700637cbSDimitry Andric  }
73*700637cbSDimitry Andric
74*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT {
75*700637cbSDimitry Andric    return operator=(static_cast<bool>(__x));
76*700637cbSDimitry Andric  }
77*700637cbSDimitry Andric
78*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void flip() _NOEXCEPT { *__seg_ ^= __mask_; }
79*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> operator&() const _NOEXCEPT {
80*700637cbSDimitry Andric    return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));
81*700637cbSDimitry Andric  }
82*700637cbSDimitry Andric
83*700637cbSDimitry Andricprivate:
84*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
85*700637cbSDimitry Andric      : __seg_(__s),
86*700637cbSDimitry Andric        __mask_(__m) {}
87*700637cbSDimitry Andric};
88*700637cbSDimitry Andric
89*700637cbSDimitry Andrictemplate <class _Cp>
90*700637cbSDimitry Andricclass __bit_reference<_Cp, false> {};
91*700637cbSDimitry Andric
92*700637cbSDimitry Andrictemplate <class _Cp>
93*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT {
94*700637cbSDimitry Andric  bool __t = __x;
95*700637cbSDimitry Andric  __x      = __y;
96*700637cbSDimitry Andric  __y      = __t;
97*700637cbSDimitry Andric}
98*700637cbSDimitry Andric
99*700637cbSDimitry Andrictemplate <class _Cp, class _Dp>
100*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT {
101*700637cbSDimitry Andric  bool __t = __x;
102*700637cbSDimitry Andric  __x      = __y;
103*700637cbSDimitry Andric  __y      = __t;
104*700637cbSDimitry Andric}
105*700637cbSDimitry Andric
106*700637cbSDimitry Andrictemplate <class _Cp>
107*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT {
108*700637cbSDimitry Andric  bool __t = __x;
109*700637cbSDimitry Andric  __x      = __y;
110*700637cbSDimitry Andric  __y      = __t;
111*700637cbSDimitry Andric}
112*700637cbSDimitry Andric
113*700637cbSDimitry Andrictemplate <class _Cp>
114*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT {
115*700637cbSDimitry Andric  bool __t = __x;
116*700637cbSDimitry Andric  __x      = __y;
117*700637cbSDimitry Andric  __y      = __t;
118*700637cbSDimitry Andric}
119*700637cbSDimitry Andric
120*700637cbSDimitry Andrictemplate <class _Cp>
121*700637cbSDimitry Andricclass __bit_const_reference {
122*700637cbSDimitry Andric  using __storage_type    = typename _Cp::__storage_type;
123*700637cbSDimitry Andric  using __storage_pointer = typename _Cp::__const_storage_pointer;
124*700637cbSDimitry Andric
125*700637cbSDimitry Andric  __storage_pointer __seg_;
126*700637cbSDimitry Andric  __storage_type __mask_;
127*700637cbSDimitry Andric
128*700637cbSDimitry Andric  friend typename _Cp::__self;
129*700637cbSDimitry Andric  friend class __bit_iterator<_Cp, true>;
130*700637cbSDimitry Andric
131*700637cbSDimitry Andricpublic:
132*700637cbSDimitry Andric  using __container = typename _Cp::__self;
133*700637cbSDimitry Andric
134*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_const_reference&) = default;
135*700637cbSDimitry Andric  __bit_const_reference& operator=(const __bit_const_reference&)            = delete;
136*700637cbSDimitry Andric
137*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
138*700637cbSDimitry Andric      : __seg_(__x.__seg_),
139*700637cbSDimitry Andric        __mask_(__x.__mask_) {}
140*700637cbSDimitry Andric
141*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI operator bool() const _NOEXCEPT { return static_cast<bool>(*__seg_ & __mask_); }
142*700637cbSDimitry Andric
143*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, true> operator&() const _NOEXCEPT {
144*700637cbSDimitry Andric    return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));
145*700637cbSDimitry Andric  }
146*700637cbSDimitry Andric
147*700637cbSDimitry Andricprivate:
148*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
149*700637cbSDimitry Andric      : __seg_(__s),
150*700637cbSDimitry Andric        __mask_(__m) {}
151*700637cbSDimitry Andric};
152*700637cbSDimitry Andric
153*700637cbSDimitry Andric// copy
154*700637cbSDimitry Andric
155*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst>
156*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned(
157*700637cbSDimitry Andric    __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
158*700637cbSDimitry Andric  using _In             = __bit_iterator<_Cp, _IsConst>;
159*700637cbSDimitry Andric  using difference_type = typename _In::difference_type;
160*700637cbSDimitry Andric  using __storage_type  = typename _In::__storage_type;
161*700637cbSDimitry Andric
162*700637cbSDimitry Andric  const int __bits_per_word = _In::__bits_per_word;
163*700637cbSDimitry Andric  difference_type __n       = __last - __first;
164*700637cbSDimitry Andric  if (__n > 0) {
165*700637cbSDimitry Andric    // do first word
166*700637cbSDimitry Andric    if (__first.__ctz_ != 0) {
167*700637cbSDimitry Andric      unsigned __clz       = __bits_per_word - __first.__ctz_;
168*700637cbSDimitry Andric      difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
169*700637cbSDimitry Andric      __n -= __dn;
170*700637cbSDimitry Andric      __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
171*700637cbSDimitry Andric      __storage_type __b = *__first.__seg_ & __m;
172*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
173*700637cbSDimitry Andric      *__result.__seg_ |= __b;
174*700637cbSDimitry Andric      __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
175*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
176*700637cbSDimitry Andric      ++__first.__seg_;
177*700637cbSDimitry Andric      // __first.__ctz_ = 0;
178*700637cbSDimitry Andric    }
179*700637cbSDimitry Andric    // __first.__ctz_ == 0;
180*700637cbSDimitry Andric    // do middle words
181*700637cbSDimitry Andric    __storage_type __nw = __n / __bits_per_word;
182*700637cbSDimitry Andric    std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_));
183*700637cbSDimitry Andric    __n -= __nw * __bits_per_word;
184*700637cbSDimitry Andric    __result.__seg_ += __nw;
185*700637cbSDimitry Andric    // do last word
186*700637cbSDimitry Andric    if (__n > 0) {
187*700637cbSDimitry Andric      __first.__seg_ += __nw;
188*700637cbSDimitry Andric      __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
189*700637cbSDimitry Andric      __storage_type __b = *__first.__seg_ & __m;
190*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
191*700637cbSDimitry Andric      *__result.__seg_ |= __b;
192*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>(__n);
193*700637cbSDimitry Andric    }
194*700637cbSDimitry Andric  }
195*700637cbSDimitry Andric  return __result;
196*700637cbSDimitry Andric}
197*700637cbSDimitry Andric
198*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst>
199*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned(
200*700637cbSDimitry Andric    __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
201*700637cbSDimitry Andric  using _In             = __bit_iterator<_Cp, _IsConst>;
202*700637cbSDimitry Andric  using difference_type = typename _In::difference_type;
203*700637cbSDimitry Andric  using __storage_type  = typename _In::__storage_type;
204*700637cbSDimitry Andric
205*700637cbSDimitry Andric  const int __bits_per_word = _In::__bits_per_word;
206*700637cbSDimitry Andric  difference_type __n       = __last - __first;
207*700637cbSDimitry Andric  if (__n > 0) {
208*700637cbSDimitry Andric    // do first word
209*700637cbSDimitry Andric    if (__first.__ctz_ != 0) {
210*700637cbSDimitry Andric      unsigned __clz_f     = __bits_per_word - __first.__ctz_;
211*700637cbSDimitry Andric      difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
212*700637cbSDimitry Andric      __n -= __dn;
213*700637cbSDimitry Andric      __storage_type __m   = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
214*700637cbSDimitry Andric      __storage_type __b   = *__first.__seg_ & __m;
215*700637cbSDimitry Andric      unsigned __clz_r     = __bits_per_word - __result.__ctz_;
216*700637cbSDimitry Andric      __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
217*700637cbSDimitry Andric      __m                  = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
218*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
219*700637cbSDimitry Andric      if (__result.__ctz_ > __first.__ctz_)
220*700637cbSDimitry Andric        *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
221*700637cbSDimitry Andric      else
222*700637cbSDimitry Andric        *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
223*700637cbSDimitry Andric      __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
224*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
225*700637cbSDimitry Andric      __dn -= __ddn;
226*700637cbSDimitry Andric      if (__dn > 0) {
227*700637cbSDimitry Andric        __m = ~__storage_type(0) >> (__bits_per_word - __dn);
228*700637cbSDimitry Andric        *__result.__seg_ &= ~__m;
229*700637cbSDimitry Andric        *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
230*700637cbSDimitry Andric        __result.__ctz_ = static_cast<unsigned>(__dn);
231*700637cbSDimitry Andric      }
232*700637cbSDimitry Andric      ++__first.__seg_;
233*700637cbSDimitry Andric      // __first.__ctz_ = 0;
234*700637cbSDimitry Andric    }
235*700637cbSDimitry Andric    // __first.__ctz_ == 0;
236*700637cbSDimitry Andric    // do middle words
237*700637cbSDimitry Andric    unsigned __clz_r   = __bits_per_word - __result.__ctz_;
238*700637cbSDimitry Andric    __storage_type __m = ~__storage_type(0) << __result.__ctz_;
239*700637cbSDimitry Andric    for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
240*700637cbSDimitry Andric      __storage_type __b = *__first.__seg_;
241*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
242*700637cbSDimitry Andric      *__result.__seg_ |= __b << __result.__ctz_;
243*700637cbSDimitry Andric      ++__result.__seg_;
244*700637cbSDimitry Andric      *__result.__seg_ &= __m;
245*700637cbSDimitry Andric      *__result.__seg_ |= __b >> __clz_r;
246*700637cbSDimitry Andric    }
247*700637cbSDimitry Andric    // do last word
248*700637cbSDimitry Andric    if (__n > 0) {
249*700637cbSDimitry Andric      __m                 = ~__storage_type(0) >> (__bits_per_word - __n);
250*700637cbSDimitry Andric      __storage_type __b  = *__first.__seg_ & __m;
251*700637cbSDimitry Andric      __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
252*700637cbSDimitry Andric      __m                 = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
253*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
254*700637cbSDimitry Andric      *__result.__seg_ |= __b << __result.__ctz_;
255*700637cbSDimitry Andric      __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
256*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
257*700637cbSDimitry Andric      __n -= __dn;
258*700637cbSDimitry Andric      if (__n > 0) {
259*700637cbSDimitry Andric        __m = ~__storage_type(0) >> (__bits_per_word - __n);
260*700637cbSDimitry Andric        *__result.__seg_ &= ~__m;
261*700637cbSDimitry Andric        *__result.__seg_ |= __b >> __dn;
262*700637cbSDimitry Andric        __result.__ctz_ = static_cast<unsigned>(__n);
263*700637cbSDimitry Andric      }
264*700637cbSDimitry Andric    }
265*700637cbSDimitry Andric  }
266*700637cbSDimitry Andric  return __result;
267*700637cbSDimitry Andric}
268*700637cbSDimitry Andric
269*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst>
270*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
271*700637cbSDimitry Andriccopy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
272*700637cbSDimitry Andric  if (__first.__ctz_ == __result.__ctz_)
273*700637cbSDimitry Andric    return std::__copy_aligned(__first, __last, __result);
274*700637cbSDimitry Andric  return std::__copy_unaligned(__first, __last, __result);
275*700637cbSDimitry Andric}
276*700637cbSDimitry Andric
277*700637cbSDimitry Andric// copy_backward
278*700637cbSDimitry Andric
279*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst>
280*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned(
281*700637cbSDimitry Andric    __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
282*700637cbSDimitry Andric  using _In             = __bit_iterator<_Cp, _IsConst>;
283*700637cbSDimitry Andric  using difference_type = typename _In::difference_type;
284*700637cbSDimitry Andric  using __storage_type  = typename _In::__storage_type;
285*700637cbSDimitry Andric
286*700637cbSDimitry Andric  const int __bits_per_word = _In::__bits_per_word;
287*700637cbSDimitry Andric  difference_type __n       = __last - __first;
288*700637cbSDimitry Andric  if (__n > 0) {
289*700637cbSDimitry Andric    // do first word
290*700637cbSDimitry Andric    if (__last.__ctz_ != 0) {
291*700637cbSDimitry Andric      difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n);
292*700637cbSDimitry Andric      __n -= __dn;
293*700637cbSDimitry Andric      unsigned __clz     = __bits_per_word - __last.__ctz_;
294*700637cbSDimitry Andric      __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
295*700637cbSDimitry Andric      __storage_type __b = *__last.__seg_ & __m;
296*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
297*700637cbSDimitry Andric      *__result.__seg_ |= __b;
298*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
299*700637cbSDimitry Andric      // __last.__ctz_ = 0
300*700637cbSDimitry Andric    }
301*700637cbSDimitry Andric    // __last.__ctz_ == 0 || __n == 0
302*700637cbSDimitry Andric    // __result.__ctz_ == 0 || __n == 0
303*700637cbSDimitry Andric    // do middle words
304*700637cbSDimitry Andric    __storage_type __nw = __n / __bits_per_word;
305*700637cbSDimitry Andric    __result.__seg_ -= __nw;
306*700637cbSDimitry Andric    __last.__seg_ -= __nw;
307*700637cbSDimitry Andric    std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_));
308*700637cbSDimitry Andric    __n -= __nw * __bits_per_word;
309*700637cbSDimitry Andric    // do last word
310*700637cbSDimitry Andric    if (__n > 0) {
311*700637cbSDimitry Andric      __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
312*700637cbSDimitry Andric      __storage_type __b = *--__last.__seg_ & __m;
313*700637cbSDimitry Andric      *--__result.__seg_ &= ~__m;
314*700637cbSDimitry Andric      *__result.__seg_ |= __b;
315*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
316*700637cbSDimitry Andric    }
317*700637cbSDimitry Andric  }
318*700637cbSDimitry Andric  return __result;
319*700637cbSDimitry Andric}
320*700637cbSDimitry Andric
321*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst>
322*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned(
323*700637cbSDimitry Andric    __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
324*700637cbSDimitry Andric  using _In             = __bit_iterator<_Cp, _IsConst>;
325*700637cbSDimitry Andric  using difference_type = typename _In::difference_type;
326*700637cbSDimitry Andric  using __storage_type  = typename _In::__storage_type;
327*700637cbSDimitry Andric
328*700637cbSDimitry Andric  const int __bits_per_word = _In::__bits_per_word;
329*700637cbSDimitry Andric  difference_type __n       = __last - __first;
330*700637cbSDimitry Andric  if (__n > 0) {
331*700637cbSDimitry Andric    // do first word
332*700637cbSDimitry Andric    if (__last.__ctz_ != 0) {
333*700637cbSDimitry Andric      difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n);
334*700637cbSDimitry Andric      __n -= __dn;
335*700637cbSDimitry Andric      unsigned __clz_l     = __bits_per_word - __last.__ctz_;
336*700637cbSDimitry Andric      __storage_type __m   = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
337*700637cbSDimitry Andric      __storage_type __b   = *__last.__seg_ & __m;
338*700637cbSDimitry Andric      unsigned __clz_r     = __bits_per_word - __result.__ctz_;
339*700637cbSDimitry Andric      __storage_type __ddn = std::min(__dn, static_cast<difference_type>(__result.__ctz_));
340*700637cbSDimitry Andric      if (__ddn > 0) {
341*700637cbSDimitry Andric        __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
342*700637cbSDimitry Andric        *__result.__seg_ &= ~__m;
343*700637cbSDimitry Andric        if (__result.__ctz_ > __last.__ctz_)
344*700637cbSDimitry Andric          *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
345*700637cbSDimitry Andric        else
346*700637cbSDimitry Andric          *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
347*700637cbSDimitry Andric        __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
348*700637cbSDimitry Andric        __dn -= __ddn;
349*700637cbSDimitry Andric      }
350*700637cbSDimitry Andric      if (__dn > 0) {
351*700637cbSDimitry Andric        // __result.__ctz_ == 0
352*700637cbSDimitry Andric        --__result.__seg_;
353*700637cbSDimitry Andric        __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
354*700637cbSDimitry Andric        __m             = ~__storage_type(0) << __result.__ctz_;
355*700637cbSDimitry Andric        *__result.__seg_ &= ~__m;
356*700637cbSDimitry Andric        __last.__ctz_ -= __dn + __ddn;
357*700637cbSDimitry Andric        *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
358*700637cbSDimitry Andric      }
359*700637cbSDimitry Andric      // __last.__ctz_ = 0
360*700637cbSDimitry Andric    }
361*700637cbSDimitry Andric    // __last.__ctz_ == 0 || __n == 0
362*700637cbSDimitry Andric    // __result.__ctz_ != 0 || __n == 0
363*700637cbSDimitry Andric    // do middle words
364*700637cbSDimitry Andric    unsigned __clz_r   = __bits_per_word - __result.__ctz_;
365*700637cbSDimitry Andric    __storage_type __m = ~__storage_type(0) >> __clz_r;
366*700637cbSDimitry Andric    for (; __n >= __bits_per_word; __n -= __bits_per_word) {
367*700637cbSDimitry Andric      __storage_type __b = *--__last.__seg_;
368*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
369*700637cbSDimitry Andric      *__result.__seg_ |= __b >> __clz_r;
370*700637cbSDimitry Andric      *--__result.__seg_ &= __m;
371*700637cbSDimitry Andric      *__result.__seg_ |= __b << __result.__ctz_;
372*700637cbSDimitry Andric    }
373*700637cbSDimitry Andric    // do last word
374*700637cbSDimitry Andric    if (__n > 0) {
375*700637cbSDimitry Andric      __m                 = ~__storage_type(0) << (__bits_per_word - __n);
376*700637cbSDimitry Andric      __storage_type __b  = *--__last.__seg_ & __m;
377*700637cbSDimitry Andric      __clz_r             = __bits_per_word - __result.__ctz_;
378*700637cbSDimitry Andric      __storage_type __dn = std::min(__n, static_cast<difference_type>(__result.__ctz_));
379*700637cbSDimitry Andric      __m                 = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
380*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
381*700637cbSDimitry Andric      *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
382*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
383*700637cbSDimitry Andric      __n -= __dn;
384*700637cbSDimitry Andric      if (__n > 0) {
385*700637cbSDimitry Andric        // __result.__ctz_ == 0
386*700637cbSDimitry Andric        --__result.__seg_;
387*700637cbSDimitry Andric        __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
388*700637cbSDimitry Andric        __m             = ~__storage_type(0) << __result.__ctz_;
389*700637cbSDimitry Andric        *__result.__seg_ &= ~__m;
390*700637cbSDimitry Andric        *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
391*700637cbSDimitry Andric      }
392*700637cbSDimitry Andric    }
393*700637cbSDimitry Andric  }
394*700637cbSDimitry Andric  return __result;
395*700637cbSDimitry Andric}
396*700637cbSDimitry Andric
397*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst>
398*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> copy_backward(
399*700637cbSDimitry Andric    __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
400*700637cbSDimitry Andric  if (__last.__ctz_ == __result.__ctz_)
401*700637cbSDimitry Andric    return std::__copy_backward_aligned(__first, __last, __result);
402*700637cbSDimitry Andric  return std::__copy_backward_unaligned(__first, __last, __result);
403*700637cbSDimitry Andric}
404*700637cbSDimitry Andric
405*700637cbSDimitry Andric// move
406*700637cbSDimitry Andric
407*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst>
408*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
409*700637cbSDimitry Andricmove(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
410*700637cbSDimitry Andric  return std::copy(__first, __last, __result);
411*700637cbSDimitry Andric}
412*700637cbSDimitry Andric
413*700637cbSDimitry Andric// move_backward
414*700637cbSDimitry Andric
415*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst>
416*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward(
417*700637cbSDimitry Andric    __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
418*700637cbSDimitry Andric  return std::copy_backward(__first, __last, __result);
419*700637cbSDimitry Andric}
420*700637cbSDimitry Andric
421*700637cbSDimitry Andric// swap_ranges
422*700637cbSDimitry Andric
423*700637cbSDimitry Andrictemplate <class _Cl, class _Cr>
424*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned(
425*700637cbSDimitry Andric    __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) {
426*700637cbSDimitry Andric  using _I1             = __bit_iterator<_Cl, false>;
427*700637cbSDimitry Andric  using difference_type = typename _I1::difference_type;
428*700637cbSDimitry Andric  using __storage_type  = typename _I1::__storage_type;
429*700637cbSDimitry Andric
430*700637cbSDimitry Andric  const int __bits_per_word = _I1::__bits_per_word;
431*700637cbSDimitry Andric  difference_type __n       = __last - __first;
432*700637cbSDimitry Andric  if (__n > 0) {
433*700637cbSDimitry Andric    // do first word
434*700637cbSDimitry Andric    if (__first.__ctz_ != 0) {
435*700637cbSDimitry Andric      unsigned __clz       = __bits_per_word - __first.__ctz_;
436*700637cbSDimitry Andric      difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
437*700637cbSDimitry Andric      __n -= __dn;
438*700637cbSDimitry Andric      __storage_type __m  = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
439*700637cbSDimitry Andric      __storage_type __b1 = *__first.__seg_ & __m;
440*700637cbSDimitry Andric      *__first.__seg_ &= ~__m;
441*700637cbSDimitry Andric      __storage_type __b2 = *__result.__seg_ & __m;
442*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
443*700637cbSDimitry Andric      *__result.__seg_ |= __b1;
444*700637cbSDimitry Andric      *__first.__seg_ |= __b2;
445*700637cbSDimitry Andric      __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
446*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
447*700637cbSDimitry Andric      ++__first.__seg_;
448*700637cbSDimitry Andric      // __first.__ctz_ = 0;
449*700637cbSDimitry Andric    }
450*700637cbSDimitry Andric    // __first.__ctz_ == 0;
451*700637cbSDimitry Andric    // do middle words
452*700637cbSDimitry Andric    for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
453*700637cbSDimitry Andric      swap(*__first.__seg_, *__result.__seg_);
454*700637cbSDimitry Andric    // do last word
455*700637cbSDimitry Andric    if (__n > 0) {
456*700637cbSDimitry Andric      __storage_type __m  = ~__storage_type(0) >> (__bits_per_word - __n);
457*700637cbSDimitry Andric      __storage_type __b1 = *__first.__seg_ & __m;
458*700637cbSDimitry Andric      *__first.__seg_ &= ~__m;
459*700637cbSDimitry Andric      __storage_type __b2 = *__result.__seg_ & __m;
460*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
461*700637cbSDimitry Andric      *__result.__seg_ |= __b1;
462*700637cbSDimitry Andric      *__first.__seg_ |= __b2;
463*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>(__n);
464*700637cbSDimitry Andric    }
465*700637cbSDimitry Andric  }
466*700637cbSDimitry Andric  return __result;
467*700637cbSDimitry Andric}
468*700637cbSDimitry Andric
469*700637cbSDimitry Andrictemplate <class _Cl, class _Cr>
470*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned(
471*700637cbSDimitry Andric    __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) {
472*700637cbSDimitry Andric  using _I1             = __bit_iterator<_Cl, false>;
473*700637cbSDimitry Andric  using difference_type = typename _I1::difference_type;
474*700637cbSDimitry Andric  using __storage_type  = typename _I1::__storage_type;
475*700637cbSDimitry Andric
476*700637cbSDimitry Andric  const int __bits_per_word = _I1::__bits_per_word;
477*700637cbSDimitry Andric  difference_type __n       = __last - __first;
478*700637cbSDimitry Andric  if (__n > 0) {
479*700637cbSDimitry Andric    // do first word
480*700637cbSDimitry Andric    if (__first.__ctz_ != 0) {
481*700637cbSDimitry Andric      unsigned __clz_f     = __bits_per_word - __first.__ctz_;
482*700637cbSDimitry Andric      difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
483*700637cbSDimitry Andric      __n -= __dn;
484*700637cbSDimitry Andric      __storage_type __m  = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
485*700637cbSDimitry Andric      __storage_type __b1 = *__first.__seg_ & __m;
486*700637cbSDimitry Andric      *__first.__seg_ &= ~__m;
487*700637cbSDimitry Andric      unsigned __clz_r     = __bits_per_word - __result.__ctz_;
488*700637cbSDimitry Andric      __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
489*700637cbSDimitry Andric      __m                  = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
490*700637cbSDimitry Andric      __storage_type __b2  = *__result.__seg_ & __m;
491*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
492*700637cbSDimitry Andric      if (__result.__ctz_ > __first.__ctz_) {
493*700637cbSDimitry Andric        unsigned __s = __result.__ctz_ - __first.__ctz_;
494*700637cbSDimitry Andric        *__result.__seg_ |= __b1 << __s;
495*700637cbSDimitry Andric        *__first.__seg_ |= __b2 >> __s;
496*700637cbSDimitry Andric      } else {
497*700637cbSDimitry Andric        unsigned __s = __first.__ctz_ - __result.__ctz_;
498*700637cbSDimitry Andric        *__result.__seg_ |= __b1 >> __s;
499*700637cbSDimitry Andric        *__first.__seg_ |= __b2 << __s;
500*700637cbSDimitry Andric      }
501*700637cbSDimitry Andric      __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
502*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
503*700637cbSDimitry Andric      __dn -= __ddn;
504*700637cbSDimitry Andric      if (__dn > 0) {
505*700637cbSDimitry Andric        __m  = ~__storage_type(0) >> (__bits_per_word - __dn);
506*700637cbSDimitry Andric        __b2 = *__result.__seg_ & __m;
507*700637cbSDimitry Andric        *__result.__seg_ &= ~__m;
508*700637cbSDimitry Andric        unsigned __s = __first.__ctz_ + __ddn;
509*700637cbSDimitry Andric        *__result.__seg_ |= __b1 >> __s;
510*700637cbSDimitry Andric        *__first.__seg_ |= __b2 << __s;
511*700637cbSDimitry Andric        __result.__ctz_ = static_cast<unsigned>(__dn);
512*700637cbSDimitry Andric      }
513*700637cbSDimitry Andric      ++__first.__seg_;
514*700637cbSDimitry Andric      // __first.__ctz_ = 0;
515*700637cbSDimitry Andric    }
516*700637cbSDimitry Andric    // __first.__ctz_ == 0;
517*700637cbSDimitry Andric    // do middle words
518*700637cbSDimitry Andric    __storage_type __m = ~__storage_type(0) << __result.__ctz_;
519*700637cbSDimitry Andric    unsigned __clz_r   = __bits_per_word - __result.__ctz_;
520*700637cbSDimitry Andric    for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
521*700637cbSDimitry Andric      __storage_type __b1 = *__first.__seg_;
522*700637cbSDimitry Andric      __storage_type __b2 = *__result.__seg_ & __m;
523*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
524*700637cbSDimitry Andric      *__result.__seg_ |= __b1 << __result.__ctz_;
525*700637cbSDimitry Andric      *__first.__seg_ = __b2 >> __result.__ctz_;
526*700637cbSDimitry Andric      ++__result.__seg_;
527*700637cbSDimitry Andric      __b2 = *__result.__seg_ & ~__m;
528*700637cbSDimitry Andric      *__result.__seg_ &= __m;
529*700637cbSDimitry Andric      *__result.__seg_ |= __b1 >> __clz_r;
530*700637cbSDimitry Andric      *__first.__seg_ |= __b2 << __clz_r;
531*700637cbSDimitry Andric    }
532*700637cbSDimitry Andric    // do last word
533*700637cbSDimitry Andric    if (__n > 0) {
534*700637cbSDimitry Andric      __m                 = ~__storage_type(0) >> (__bits_per_word - __n);
535*700637cbSDimitry Andric      __storage_type __b1 = *__first.__seg_ & __m;
536*700637cbSDimitry Andric      *__first.__seg_ &= ~__m;
537*700637cbSDimitry Andric      __storage_type __dn = std::min<__storage_type>(__n, __clz_r);
538*700637cbSDimitry Andric      __m                 = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
539*700637cbSDimitry Andric      __storage_type __b2 = *__result.__seg_ & __m;
540*700637cbSDimitry Andric      *__result.__seg_ &= ~__m;
541*700637cbSDimitry Andric      *__result.__seg_ |= __b1 << __result.__ctz_;
542*700637cbSDimitry Andric      *__first.__seg_ |= __b2 >> __result.__ctz_;
543*700637cbSDimitry Andric      __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
544*700637cbSDimitry Andric      __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
545*700637cbSDimitry Andric      __n -= __dn;
546*700637cbSDimitry Andric      if (__n > 0) {
547*700637cbSDimitry Andric        __m  = ~__storage_type(0) >> (__bits_per_word - __n);
548*700637cbSDimitry Andric        __b2 = *__result.__seg_ & __m;
549*700637cbSDimitry Andric        *__result.__seg_ &= ~__m;
550*700637cbSDimitry Andric        *__result.__seg_ |= __b1 >> __dn;
551*700637cbSDimitry Andric        *__first.__seg_ |= __b2 << __dn;
552*700637cbSDimitry Andric        __result.__ctz_ = static_cast<unsigned>(__n);
553*700637cbSDimitry Andric      }
554*700637cbSDimitry Andric    }
555*700637cbSDimitry Andric  }
556*700637cbSDimitry Andric  return __result;
557*700637cbSDimitry Andric}
558*700637cbSDimitry Andric
559*700637cbSDimitry Andrictemplate <class _Cl, class _Cr>
560*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges(
561*700637cbSDimitry Andric    __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) {
562*700637cbSDimitry Andric  if (__first1.__ctz_ == __first2.__ctz_)
563*700637cbSDimitry Andric    return std::__swap_ranges_aligned(__first1, __last1, __first2);
564*700637cbSDimitry Andric  return std::__swap_ranges_unaligned(__first1, __last1, __first2);
565*700637cbSDimitry Andric}
566*700637cbSDimitry Andric
567*700637cbSDimitry Andric// rotate
568*700637cbSDimitry Andric
569*700637cbSDimitry Andrictemplate <class _Cp>
570*700637cbSDimitry Andricstruct __bit_array {
571*700637cbSDimitry Andric  using difference_type   = typename _Cp::difference_type;
572*700637cbSDimitry Andric  using __storage_type    = typename _Cp::__storage_type;
573*700637cbSDimitry Andric  using __storage_pointer = typename _Cp::__storage_pointer;
574*700637cbSDimitry Andric  using iterator          = typename _Cp::iterator;
575*700637cbSDimitry Andric
576*700637cbSDimitry Andric  static const unsigned __bits_per_word = _Cp::__bits_per_word;
577*700637cbSDimitry Andric  static const unsigned _Np             = 4;
578*700637cbSDimitry Andric
579*700637cbSDimitry Andric  difference_type __size_;
580*700637cbSDimitry Andric  __storage_type __word_[_Np];
581*700637cbSDimitry Andric
582*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static difference_type capacity() {
583*700637cbSDimitry Andric    return static_cast<difference_type>(_Np * __bits_per_word);
584*700637cbSDimitry Andric  }
585*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __bit_array(difference_type __s) : __size_(__s) {
586*700637cbSDimitry Andric    if (__libcpp_is_constant_evaluated()) {
587*700637cbSDimitry Andric      for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i)
588*700637cbSDimitry Andric        std::__construct_at(__word_ + __i, 0);
589*700637cbSDimitry Andric    }
590*700637cbSDimitry Andric  }
591*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator begin() {
592*700637cbSDimitry Andric    return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
593*700637cbSDimitry Andric  }
594*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI iterator end() {
595*700637cbSDimitry Andric    return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
596*700637cbSDimitry Andric                    static_cast<unsigned>(__size_ % __bits_per_word));
597*700637cbSDimitry Andric  }
598*700637cbSDimitry Andric};
599*700637cbSDimitry Andric
600*700637cbSDimitry Andrictemplate <class _Cp>
601*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
602*700637cbSDimitry Andricrotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) {
603*700637cbSDimitry Andric  using _I1             = __bit_iterator<_Cp, false>;
604*700637cbSDimitry Andric  using difference_type = typename _I1::difference_type;
605*700637cbSDimitry Andric
606*700637cbSDimitry Andric  difference_type __d1 = __middle - __first;
607*700637cbSDimitry Andric  difference_type __d2 = __last - __middle;
608*700637cbSDimitry Andric  _I1 __r              = __first + __d2;
609*700637cbSDimitry Andric  while (__d1 != 0 && __d2 != 0) {
610*700637cbSDimitry Andric    if (__d1 <= __d2) {
611*700637cbSDimitry Andric      if (__d1 <= __bit_array<_Cp>::capacity()) {
612*700637cbSDimitry Andric        __bit_array<_Cp> __b(__d1);
613*700637cbSDimitry Andric        std::copy(__first, __middle, __b.begin());
614*700637cbSDimitry Andric        std::copy(__b.begin(), __b.end(), std::copy(__middle, __last, __first));
615*700637cbSDimitry Andric        break;
616*700637cbSDimitry Andric      } else {
617*700637cbSDimitry Andric        __bit_iterator<_Cp, false> __mp = std::swap_ranges(__first, __middle, __middle);
618*700637cbSDimitry Andric        __first                         = __middle;
619*700637cbSDimitry Andric        __middle                        = __mp;
620*700637cbSDimitry Andric        __d2 -= __d1;
621*700637cbSDimitry Andric      }
622*700637cbSDimitry Andric    } else {
623*700637cbSDimitry Andric      if (__d2 <= __bit_array<_Cp>::capacity()) {
624*700637cbSDimitry Andric        __bit_array<_Cp> __b(__d2);
625*700637cbSDimitry Andric        std::copy(__middle, __last, __b.begin());
626*700637cbSDimitry Andric        std::copy_backward(__b.begin(), __b.end(), std::copy_backward(__first, __middle, __last));
627*700637cbSDimitry Andric        break;
628*700637cbSDimitry Andric      } else {
629*700637cbSDimitry Andric        __bit_iterator<_Cp, false> __mp = __first + __d2;
630*700637cbSDimitry Andric        std::swap_ranges(__first, __mp, __middle);
631*700637cbSDimitry Andric        __first = __mp;
632*700637cbSDimitry Andric        __d1 -= __d2;
633*700637cbSDimitry Andric      }
634*700637cbSDimitry Andric    }
635*700637cbSDimitry Andric  }
636*700637cbSDimitry Andric  return __r;
637*700637cbSDimitry Andric}
638*700637cbSDimitry Andric
639*700637cbSDimitry Andric// equal
640*700637cbSDimitry Andric
641*700637cbSDimitry Andrictemplate <class _Cp, bool _IC1, bool _IC2>
642*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool __equal_unaligned(
643*700637cbSDimitry Andric    __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
644*700637cbSDimitry Andric  using _It             = __bit_iterator<_Cp, _IC1>;
645*700637cbSDimitry Andric  using difference_type = typename _It::difference_type;
646*700637cbSDimitry Andric  using __storage_type  = typename _It::__storage_type;
647*700637cbSDimitry Andric
648*700637cbSDimitry Andric  const int __bits_per_word = _It::__bits_per_word;
649*700637cbSDimitry Andric  difference_type __n       = __last1 - __first1;
650*700637cbSDimitry Andric  if (__n > 0) {
651*700637cbSDimitry Andric    // do first word
652*700637cbSDimitry Andric    if (__first1.__ctz_ != 0) {
653*700637cbSDimitry Andric      unsigned __clz_f     = __bits_per_word - __first1.__ctz_;
654*700637cbSDimitry Andric      difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
655*700637cbSDimitry Andric      __n -= __dn;
656*700637cbSDimitry Andric      __storage_type __m   = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
657*700637cbSDimitry Andric      __storage_type __b   = *__first1.__seg_ & __m;
658*700637cbSDimitry Andric      unsigned __clz_r     = __bits_per_word - __first2.__ctz_;
659*700637cbSDimitry Andric      __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
660*700637cbSDimitry Andric      __m                  = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
661*700637cbSDimitry Andric      if (__first2.__ctz_ > __first1.__ctz_) {
662*700637cbSDimitry Andric        if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
663*700637cbSDimitry Andric          return false;
664*700637cbSDimitry Andric      } else {
665*700637cbSDimitry Andric        if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
666*700637cbSDimitry Andric          return false;
667*700637cbSDimitry Andric      }
668*700637cbSDimitry Andric      __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
669*700637cbSDimitry Andric      __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word);
670*700637cbSDimitry Andric      __dn -= __ddn;
671*700637cbSDimitry Andric      if (__dn > 0) {
672*700637cbSDimitry Andric        __m = ~__storage_type(0) >> (__bits_per_word - __dn);
673*700637cbSDimitry Andric        if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
674*700637cbSDimitry Andric          return false;
675*700637cbSDimitry Andric        __first2.__ctz_ = static_cast<unsigned>(__dn);
676*700637cbSDimitry Andric      }
677*700637cbSDimitry Andric      ++__first1.__seg_;
678*700637cbSDimitry Andric      // __first1.__ctz_ = 0;
679*700637cbSDimitry Andric    }
680*700637cbSDimitry Andric    // __first1.__ctz_ == 0;
681*700637cbSDimitry Andric    // do middle words
682*700637cbSDimitry Andric    unsigned __clz_r   = __bits_per_word - __first2.__ctz_;
683*700637cbSDimitry Andric    __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
684*700637cbSDimitry Andric    for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) {
685*700637cbSDimitry Andric      __storage_type __b = *__first1.__seg_;
686*700637cbSDimitry Andric      if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
687*700637cbSDimitry Andric        return false;
688*700637cbSDimitry Andric      ++__first2.__seg_;
689*700637cbSDimitry Andric      if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
690*700637cbSDimitry Andric        return false;
691*700637cbSDimitry Andric    }
692*700637cbSDimitry Andric    // do last word
693*700637cbSDimitry Andric    if (__n > 0) {
694*700637cbSDimitry Andric      __m                 = ~__storage_type(0) >> (__bits_per_word - __n);
695*700637cbSDimitry Andric      __storage_type __b  = *__first1.__seg_ & __m;
696*700637cbSDimitry Andric      __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
697*700637cbSDimitry Andric      __m                 = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
698*700637cbSDimitry Andric      if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
699*700637cbSDimitry Andric        return false;
700*700637cbSDimitry Andric      __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
701*700637cbSDimitry Andric      __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word);
702*700637cbSDimitry Andric      __n -= __dn;
703*700637cbSDimitry Andric      if (__n > 0) {
704*700637cbSDimitry Andric        __m = ~__storage_type(0) >> (__bits_per_word - __n);
705*700637cbSDimitry Andric        if ((*__first2.__seg_ & __m) != (__b >> __dn))
706*700637cbSDimitry Andric          return false;
707*700637cbSDimitry Andric      }
708*700637cbSDimitry Andric    }
709*700637cbSDimitry Andric  }
710*700637cbSDimitry Andric  return true;
711*700637cbSDimitry Andric}
712*700637cbSDimitry Andric
713*700637cbSDimitry Andrictemplate <class _Cp, bool _IC1, bool _IC2>
714*700637cbSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool __equal_aligned(
715*700637cbSDimitry Andric    __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
716*700637cbSDimitry Andric  using _It             = __bit_iterator<_Cp, _IC1>;
717*700637cbSDimitry Andric  using difference_type = typename _It::difference_type;
718*700637cbSDimitry Andric  using __storage_type  = typename _It::__storage_type;
719*700637cbSDimitry Andric
720*700637cbSDimitry Andric  const int __bits_per_word = _It::__bits_per_word;
721*700637cbSDimitry Andric  difference_type __n       = __last1 - __first1;
722*700637cbSDimitry Andric  if (__n > 0) {
723*700637cbSDimitry Andric    // do first word
724*700637cbSDimitry Andric    if (__first1.__ctz_ != 0) {
725*700637cbSDimitry Andric      unsigned __clz       = __bits_per_word - __first1.__ctz_;
726*700637cbSDimitry Andric      difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
727*700637cbSDimitry Andric      __n -= __dn;
728*700637cbSDimitry Andric      __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
729*700637cbSDimitry Andric      if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
730*700637cbSDimitry Andric        return false;
731*700637cbSDimitry Andric      ++__first2.__seg_;
732*700637cbSDimitry Andric      ++__first1.__seg_;
733*700637cbSDimitry Andric      // __first1.__ctz_ = 0;
734*700637cbSDimitry Andric      // __first2.__ctz_ = 0;
735*700637cbSDimitry Andric    }
736*700637cbSDimitry Andric    // __first1.__ctz_ == 0;
737*700637cbSDimitry Andric    // __first2.__ctz_ == 0;
738*700637cbSDimitry Andric    // do middle words
739*700637cbSDimitry Andric    for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
740*700637cbSDimitry Andric      if (*__first2.__seg_ != *__first1.__seg_)
741*700637cbSDimitry Andric        return false;
742*700637cbSDimitry Andric    // do last word
743*700637cbSDimitry Andric    if (__n > 0) {
744*700637cbSDimitry Andric      __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
745*700637cbSDimitry Andric      if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
746*700637cbSDimitry Andric        return false;
747*700637cbSDimitry Andric    }
748*700637cbSDimitry Andric  }
749*700637cbSDimitry Andric  return true;
750*700637cbSDimitry Andric}
751*700637cbSDimitry Andric
752*700637cbSDimitry Andrictemplate <class _Cp, bool _IC1, bool _IC2>
753*700637cbSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool
754*700637cbSDimitry Andricequal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
755*700637cbSDimitry Andric  if (__first1.__ctz_ == __first2.__ctz_)
756*700637cbSDimitry Andric    return std::__equal_aligned(__first1, __last1, __first2);
757*700637cbSDimitry Andric  return std::__equal_unaligned(__first1, __last1, __first2);
758*700637cbSDimitry Andric}
759*700637cbSDimitry Andric
760*700637cbSDimitry Andrictemplate <class _Cp, bool _IsConst, typename _Cp::__storage_type>
761*700637cbSDimitry Andricclass __bit_iterator {
762*700637cbSDimitry Andricpublic:
763*700637cbSDimitry Andric  using difference_type = typename _Cp::difference_type;
764*700637cbSDimitry Andric  using value_type      = bool;
765*700637cbSDimitry Andric  using pointer         = __bit_iterator;
766*700637cbSDimitry Andric#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
767*700637cbSDimitry Andric  using reference = __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >;
768*700637cbSDimitry Andric#else
769*700637cbSDimitry Andric  using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >;
770*700637cbSDimitry Andric#endif
771*700637cbSDimitry Andric  using iterator_category = random_access_iterator_tag;
772*700637cbSDimitry Andric
773*700637cbSDimitry Andricprivate:
774*700637cbSDimitry Andric  using __storage_type = typename _Cp::__storage_type;
775*700637cbSDimitry Andric  using __storage_pointer =
776*700637cbSDimitry Andric      __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>;
777*700637cbSDimitry Andric
778*700637cbSDimitry Andric  static const unsigned __bits_per_word = _Cp::__bits_per_word;
779*700637cbSDimitry Andric
780*700637cbSDimitry Andric  __storage_pointer __seg_;
781*700637cbSDimitry Andric  unsigned __ctz_;
782*700637cbSDimitry Andric
783*700637cbSDimitry Andricpublic:
784*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator() _NOEXCEPT {}
785*700637cbSDimitry Andric
786*700637cbSDimitry Andric  // When _IsConst=false, this is the copy constructor.
787*700637cbSDimitry Andric  // It is non-trivial. Making it trivial would break ABI.
788*700637cbSDimitry Andric  // When _IsConst=true, this is a converting constructor;
789*700637cbSDimitry Andric  // the copy and move constructors are implicitly generated
790*700637cbSDimitry Andric  // and trivial.
791*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
792*700637cbSDimitry Andric      : __seg_(__it.__seg_),
793*700637cbSDimitry Andric        __ctz_(__it.__ctz_) {}
794*700637cbSDimitry Andric
795*700637cbSDimitry Andric  // When _IsConst=false, we have a user-provided copy constructor,
796*700637cbSDimitry Andric  // so we must also provide a copy assignment operator because
797*700637cbSDimitry Andric  // the implicit generation of a defaulted one is deprecated.
798*700637cbSDimitry Andric  // When _IsConst=true, the assignment operators are
799*700637cbSDimitry Andric  // implicitly generated and trivial.
800*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
801*700637cbSDimitry Andric    __seg_ = __it.__seg_;
802*700637cbSDimitry Andric    __ctz_ = __it.__ctz_;
803*700637cbSDimitry Andric    return *this;
804*700637cbSDimitry Andric  }
805*700637cbSDimitry Andric
806*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference operator*() const _NOEXCEPT {
807*700637cbSDimitry Andric    return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >(
808*700637cbSDimitry Andric        __seg_, __storage_type(1) << __ctz_);
809*700637cbSDimitry Andric  }
810*700637cbSDimitry Andric
811*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator& operator++() {
812*700637cbSDimitry Andric    if (__ctz_ != __bits_per_word - 1)
813*700637cbSDimitry Andric      ++__ctz_;
814*700637cbSDimitry Andric    else {
815*700637cbSDimitry Andric      __ctz_ = 0;
816*700637cbSDimitry Andric      ++__seg_;
817*700637cbSDimitry Andric    }
818*700637cbSDimitry Andric    return *this;
819*700637cbSDimitry Andric  }
820*700637cbSDimitry Andric
821*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator operator++(int) {
822*700637cbSDimitry Andric    __bit_iterator __tmp = *this;
823*700637cbSDimitry Andric    ++(*this);
824*700637cbSDimitry Andric    return __tmp;
825*700637cbSDimitry Andric  }
826*700637cbSDimitry Andric
827*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator& operator--() {
828*700637cbSDimitry Andric    if (__ctz_ != 0)
829*700637cbSDimitry Andric      --__ctz_;
830*700637cbSDimitry Andric    else {
831*700637cbSDimitry Andric      __ctz_ = __bits_per_word - 1;
832*700637cbSDimitry Andric      --__seg_;
833*700637cbSDimitry Andric    }
834*700637cbSDimitry Andric    return *this;
835*700637cbSDimitry Andric  }
836*700637cbSDimitry Andric
837*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator operator--(int) {
838*700637cbSDimitry Andric    __bit_iterator __tmp = *this;
839*700637cbSDimitry Andric    --(*this);
840*700637cbSDimitry Andric    return __tmp;
841*700637cbSDimitry Andric  }
842*700637cbSDimitry Andric
843*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator& operator+=(difference_type __n) {
844*700637cbSDimitry Andric    if (__n >= 0)
845*700637cbSDimitry Andric      __seg_ += (__n + __ctz_) / __bits_per_word;
846*700637cbSDimitry Andric    else
847*700637cbSDimitry Andric      __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) /
848*700637cbSDimitry Andric                static_cast<difference_type>(__bits_per_word);
849*700637cbSDimitry Andric    __n &= (__bits_per_word - 1);
850*700637cbSDimitry Andric    __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word);
851*700637cbSDimitry Andric    return *this;
852*700637cbSDimitry Andric  }
853*700637cbSDimitry Andric
854*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator& operator-=(difference_type __n) { return *this += -__n; }
855*700637cbSDimitry Andric
856*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator operator+(difference_type __n) const {
857*700637cbSDimitry Andric    __bit_iterator __t(*this);
858*700637cbSDimitry Andric    __t += __n;
859*700637cbSDimitry Andric    return __t;
860*700637cbSDimitry Andric  }
861*700637cbSDimitry Andric
862*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI __bit_iterator operator-(difference_type __n) const {
863*700637cbSDimitry Andric    __bit_iterator __t(*this);
864*700637cbSDimitry Andric    __t -= __n;
865*700637cbSDimitry Andric    return __t;
866*700637cbSDimitry Andric  }
867*700637cbSDimitry Andric
868*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {
869*700637cbSDimitry Andric    return __it + __n;
870*700637cbSDimitry Andric  }
871*700637cbSDimitry Andric
872*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) {
873*700637cbSDimitry Andric    return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;
874*700637cbSDimitry Andric  }
875*700637cbSDimitry Andric
876*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const { return *(*this + __n); }
877*700637cbSDimitry Andric
878*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) {
879*700637cbSDimitry Andric    return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;
880*700637cbSDimitry Andric  }
881*700637cbSDimitry Andric
882*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) {
883*700637cbSDimitry Andric    return !(__x == __y);
884*700637cbSDimitry Andric  }
885*700637cbSDimitry Andric
886*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) {
887*700637cbSDimitry Andric    return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);
888*700637cbSDimitry Andric  }
889*700637cbSDimitry Andric
890*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) {
891*700637cbSDimitry Andric    return __y < __x;
892*700637cbSDimitry Andric  }
893*700637cbSDimitry Andric
894*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) {
895*700637cbSDimitry Andric    return !(__y < __x);
896*700637cbSDimitry Andric  }
897*700637cbSDimitry Andric
898*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) {
899*700637cbSDimitry Andric    return !(__x < __y);
900*700637cbSDimitry Andric  }
901*700637cbSDimitry Andric
902*700637cbSDimitry Andricprivate:
903*700637cbSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
904*700637cbSDimitry Andric      : __seg_(__s),
905*700637cbSDimitry Andric        __ctz_(__ctz) {}
906*700637cbSDimitry Andric
907*700637cbSDimitry Andric  friend typename _Cp::__self;
908*700637cbSDimitry Andric
909*700637cbSDimitry Andric  friend class __bit_reference<_Cp>;
910*700637cbSDimitry Andric  friend class __bit_const_reference<_Cp>;
911*700637cbSDimitry Andric  friend class __bit_iterator<_Cp, true>;
912*700637cbSDimitry Andric  template <class _Dp>
913*700637cbSDimitry Andric  friend struct __bit_array;
914*700637cbSDimitry Andric
915*700637cbSDimitry Andric  template <bool _FillVal, class _Dp>
916*700637cbSDimitry Andric  friend void __fill_n_bool(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
917*700637cbSDimitry Andric
918*700637cbSDimitry Andric  template <class _Dp, bool _IC>
919*700637cbSDimitry Andric  friend __bit_iterator<_Dp, false> __copy_aligned(
920*700637cbSDimitry Andric      __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
921*700637cbSDimitry Andric  template <class _Dp, bool _IC>
922*700637cbSDimitry Andric  friend __bit_iterator<_Dp, false> __copy_unaligned(
923*700637cbSDimitry Andric      __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
924*700637cbSDimitry Andric  template <class _Dp, bool _IC>
925*700637cbSDimitry Andric  friend __bit_iterator<_Dp, false>
926*700637cbSDimitry Andric  copy(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
927*700637cbSDimitry Andric  template <class _Dp, bool _IC>
928*700637cbSDimitry Andric  friend __bit_iterator<_Dp, false> __copy_backward_aligned(
929*700637cbSDimitry Andric      __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
930*700637cbSDimitry Andric  template <class _Dp, bool _IC>
931*700637cbSDimitry Andric  friend __bit_iterator<_Dp, false> __copy_backward_unaligned(
932*700637cbSDimitry Andric      __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
933*700637cbSDimitry Andric  template <class _Dp, bool _IC>
934*700637cbSDimitry Andric  friend __bit_iterator<_Dp, false>
935*700637cbSDimitry Andric  copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
936*700637cbSDimitry Andric  template <class _Cl, class _Cr>
937*700637cbSDimitry Andric  friend __bit_iterator<_Cr, false>
938*700637cbSDimitry Andric      __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
939*700637cbSDimitry Andric  template <class _Cl, class _Cr>
940*700637cbSDimitry Andric  friend __bit_iterator<_Cr, false>
941*700637cbSDimitry Andric      __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
942*700637cbSDimitry Andric  template <class _Cl, class _Cr>
943*700637cbSDimitry Andric  friend __bit_iterator<_Cr, false>
944*700637cbSDimitry Andric      swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
945*700637cbSDimitry Andric  template <class _Dp>
946*700637cbSDimitry Andric  friend __bit_iterator<_Dp, false>
947*700637cbSDimitry Andric      rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>);
948*700637cbSDimitry Andric  template <class _Dp, bool _IC1, bool _IC2>
949*700637cbSDimitry Andric  friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
950*700637cbSDimitry Andric  template <class _Dp, bool _IC1, bool _IC2>
951*700637cbSDimitry Andric  friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
952*700637cbSDimitry Andric  template <class _Dp, bool _IC1, bool _IC2>
953*700637cbSDimitry Andric  friend bool equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
954*700637cbSDimitry Andric  template <bool _ToFind, class _Dp, bool _IC>
955*700637cbSDimitry Andric  friend __bit_iterator<_Dp, _IC> __find_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
956*700637cbSDimitry Andric  template <bool _ToCount, class _Dp, bool _IC>
957*700637cbSDimitry Andric  friend typename __bit_iterator<_Dp, _IC>::difference_type
958*700637cbSDimitry Andric      _LIBCPP_HIDE_FROM_ABI __count_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
959*700637cbSDimitry Andric};
960*700637cbSDimitry Andric
961*700637cbSDimitry Andric_LIBCPP_END_NAMESPACE_STD
962*700637cbSDimitry Andric
963*700637cbSDimitry Andric_LIBCPP_POP_MACROS
964*700637cbSDimitry Andric
965*700637cbSDimitry Andric#endif // _LIBCPP___CXX03___BIT_REFERENCE
966