@@ -179,47 +179,18 @@ private:
179179 __bit_const_reference& operator =(const __bit_const_reference&) = delete ;
180180};
181181
182- // find
183-
184- template <class _Cp , bool _IsConst>
185- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst>
186- __find_bool_true (__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
187- {
188- typedef __bit_iterator<_Cp, _IsConst> _It;
189- typedef typename _It::__storage_type __storage_type;
190- const int __bits_per_word = _It::__bits_per_word;
191- // do first partial word
192- if (__first.__ctz_ != 0 )
193- {
194- __storage_type __clz_f = static_cast <__storage_type>(__bits_per_word - __first.__ctz_ );
195- __storage_type __dn = _VSTD::min (__clz_f, __n);
196- __storage_type __m = (~__storage_type (0 ) << __first.__ctz_ ) & (~__storage_type (0 ) >> (__clz_f - __dn));
197- __storage_type __b = *__first.__seg_ & __m;
198- if (__b)
199- return _It (__first.__seg_ , static_cast <unsigned >(_VSTD::__libcpp_ctz (__b)));
200- if (__n == __dn)
201- return __first + __n;
202- __n -= __dn;
203- ++__first.__seg_ ;
204- }
205- // do middle whole words
206- for (; __n >= __bits_per_word; ++__first.__seg_ , __n -= __bits_per_word)
207- if (*__first.__seg_ )
208- return _It (__first.__seg_ , static_cast <unsigned >(_VSTD::__libcpp_ctz (*__first.__seg_ )));
209- // do last partial word
210- if (__n > 0 )
211- {
212- __storage_type __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
213- __storage_type __b = *__first.__seg_ & __m;
214- if (__b)
215- return _It (__first.__seg_ , static_cast <unsigned >(_VSTD::__libcpp_ctz (__b)));
216- }
217- return _It (__first.__seg_ , static_cast <unsigned >(__n));
182+ template <bool _Invert, class _Tp >
183+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __invert_if (_Tp __v) {
184+ if (_Invert)
185+ return ~__v;
186+ return __v;
218187}
219188
220- template <class _Cp , bool _IsConst>
189+ // find
190+
191+ template <bool _ToFind, class _Cp , bool _IsConst>
221192_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst>
222- __find_bool_false (__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
193+ __find_bool (__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
223194{
224195 typedef __bit_iterator<_Cp, _IsConst> _It;
225196 typedef typename _It::__storage_type __storage_type;
@@ -230,7 +201,7 @@ __find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type
230201 __storage_type __clz_f = static_cast <__storage_type>(__bits_per_word - __first.__ctz_ );
231202 __storage_type __dn = _VSTD::min (__clz_f, __n);
232203 __storage_type __m = (~__storage_type (0 ) << __first.__ctz_ ) & (~__storage_type (0 ) >> (__clz_f - __dn));
233- __storage_type __b = ~ *__first.__seg_ & __m;
204+ __storage_type __b = std::__invert_if<!_ToFind>( *__first.__seg_ ) & __m;
234205 if (__b)
235206 return _It (__first.__seg_ , static_cast <unsigned >(_VSTD::__libcpp_ctz (__b)));
236207 if (__n == __dn)
@@ -239,17 +210,16 @@ __find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type
239210 ++__first.__seg_ ;
240211 }
241212 // do middle whole words
242- for (; __n >= __bits_per_word; ++__first.__seg_ , __n -= __bits_per_word)
243- {
244- __storage_type __b = ~*__first.__seg_ ;
213+ for (; __n >= __bits_per_word; ++__first.__seg_ , __n -= __bits_per_word) {
214+ __storage_type __b = std::__invert_if<!_ToFind>(*__first.__seg_ );
245215 if (__b)
246216 return _It (__first.__seg_ , static_cast <unsigned >(_VSTD::__libcpp_ctz (__b)));
247217 }
248218 // do last partial word
249219 if (__n > 0 )
250220 {
251221 __storage_type __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
252- __storage_type __b = ~ *__first.__seg_ & __m;
222+ __storage_type __b = std::__invert_if<!_ToFind>( *__first.__seg_ ) & __m;
253223 if (__b)
254224 return _It (__first.__seg_ , static_cast <unsigned >(_VSTD::__libcpp_ctz (__b)));
255225 }
@@ -262,15 +232,15 @@ __bit_iterator<_Cp, _IsConst>
262232find (__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value)
263233{
264234 if (static_cast <bool >(__value))
265- return _VSTD::__find_bool_true (__first, static_cast <typename _Cp::size_type>(__last - __first));
266- return _VSTD::__find_bool_false (__first, static_cast <typename _Cp::size_type>(__last - __first));
235+ return _VSTD::__find_bool< true > (__first, static_cast <typename _Cp::size_type>(__last - __first));
236+ return _VSTD::__find_bool< false > (__first, static_cast <typename _Cp::size_type>(__last - __first));
267237}
268238
269239// count
270240
271- template <class _Cp , bool _IsConst>
241+ template <bool _ToCount, class _Cp , bool _IsConst>
272242_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __bit_iterator<_Cp, _IsConst>::difference_type
273- __count_bool_true (__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
243+ __count_bool (__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
274244{
275245 typedef __bit_iterator<_Cp, _IsConst> _It;
276246 typedef typename _It::__storage_type __storage_type;
@@ -283,49 +253,18 @@ __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type
283253 __storage_type __clz_f = static_cast <__storage_type>(__bits_per_word - __first.__ctz_ );
284254 __storage_type __dn = _VSTD::min (__clz_f, __n);
285255 __storage_type __m = (~__storage_type (0 ) << __first.__ctz_ ) & (~__storage_type (0 ) >> (__clz_f - __dn));
286- __r = _VSTD::__libcpp_popcount (*__first.__seg_ & __m);
256+ __r = _VSTD::__libcpp_popcount (std::__invert_if<!_ToCount>( *__first.__seg_ ) & __m);
287257 __n -= __dn;
288258 ++__first.__seg_ ;
289259 }
290260 // do middle whole words
291261 for (; __n >= __bits_per_word; ++__first.__seg_ , __n -= __bits_per_word)
292- __r += _VSTD::__libcpp_popcount (*__first.__seg_ );
262+ __r += _VSTD::__libcpp_popcount (std::__invert_if<!_ToCount>( *__first.__seg_ ) );
293263 // do last partial word
294264 if (__n > 0 )
295265 {
296266 __storage_type __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
297- __r += _VSTD::__libcpp_popcount (*__first.__seg_ & __m);
298- }
299- return __r;
300- }
301-
302- template <class _Cp , bool _IsConst>
303- _LIBCPP_HIDE_FROM_ABI typename __bit_iterator<_Cp, _IsConst>::difference_type
304- __count_bool_false (__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
305- {
306- typedef __bit_iterator<_Cp, _IsConst> _It;
307- typedef typename _It::__storage_type __storage_type;
308- typedef typename _It::difference_type difference_type;
309- const int __bits_per_word = _It::__bits_per_word;
310- difference_type __r = 0 ;
311- // do first partial word
312- if (__first.__ctz_ != 0 )
313- {
314- __storage_type __clz_f = static_cast <__storage_type>(__bits_per_word - __first.__ctz_ );
315- __storage_type __dn = _VSTD::min (__clz_f, __n);
316- __storage_type __m = (~__storage_type (0 ) << __first.__ctz_ ) & (~__storage_type (0 ) >> (__clz_f - __dn));
317- __r = _VSTD::__libcpp_popcount (~*__first.__seg_ & __m);
318- __n -= __dn;
319- ++__first.__seg_ ;
320- }
321- // do middle whole words
322- for (; __n >= __bits_per_word; ++__first.__seg_ , __n -= __bits_per_word)
323- __r += _VSTD::__libcpp_popcount (~*__first.__seg_ );
324- // do last partial word
325- if (__n > 0 )
326- {
327- __storage_type __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
328- __r += _VSTD::__libcpp_popcount (~*__first.__seg_ & __m);
267+ __r += _VSTD::__libcpp_popcount (std::__invert_if<!_ToCount>(*__first.__seg_ ) & __m);
329268 }
330269 return __r;
331270}
@@ -336,45 +275,15 @@ typename __bit_iterator<_Cp, _IsConst>::difference_type
336275count (__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value)
337276{
338277 if (static_cast <bool >(__value))
339- return _VSTD::__count_bool_true (__first, static_cast <typename _Cp::size_type>(__last - __first));
340- return _VSTD::__count_bool_false (__first, static_cast <typename _Cp::size_type>(__last - __first));
278+ return _VSTD::__count_bool< true > (__first, static_cast <typename _Cp::size_type>(__last - __first));
279+ return _VSTD::__count_bool< false > (__first, static_cast <typename _Cp::size_type>(__last - __first));
341280}
342281
343282// fill_n
344283
345- template <class _Cp >
346- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
347- __fill_n_false (__bit_iterator<_Cp, false > __first, typename _Cp::size_type __n)
348- {
349- typedef __bit_iterator<_Cp, false > _It;
350- typedef typename _It::__storage_type __storage_type;
351- const int __bits_per_word = _It::__bits_per_word;
352- // do first partial word
353- if (__first.__ctz_ != 0 )
354- {
355- __storage_type __clz_f = static_cast <__storage_type>(__bits_per_word - __first.__ctz_ );
356- __storage_type __dn = _VSTD::min (__clz_f, __n);
357- __storage_type __m = (~__storage_type (0 ) << __first.__ctz_ ) & (~__storage_type (0 ) >> (__clz_f - __dn));
358- *__first.__seg_ &= ~__m;
359- __n -= __dn;
360- ++__first.__seg_ ;
361- }
362- // do middle whole words
363- __storage_type __nw = __n / __bits_per_word;
364- std::fill_n (std::__to_address (__first.__seg_ ), __nw, 0 );
365- __n -= __nw * __bits_per_word;
366- // do last partial word
367- if (__n > 0 )
368- {
369- __first.__seg_ += __nw;
370- __storage_type __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
371- *__first.__seg_ &= ~__m;
372- }
373- }
374-
375- template <class _Cp >
284+ template <bool _FillValue, class _Cp >
376285_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
377- __fill_n_true (__bit_iterator<_Cp, false > __first, typename _Cp::size_type __n)
286+ __fill_n (__bit_iterator<_Cp, false > __first, typename _Cp::size_type __n)
378287{
379288 typedef __bit_iterator<_Cp, false > _It;
380289 typedef typename _It::__storage_type __storage_type;
@@ -385,21 +294,26 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
385294 __storage_type __clz_f = static_cast <__storage_type>(__bits_per_word - __first.__ctz_ );
386295 __storage_type __dn = _VSTD::min (__clz_f, __n);
387296 __storage_type __m = (~__storage_type (0 ) << __first.__ctz_ ) & (~__storage_type (0 ) >> (__clz_f - __dn));
388- *__first.__seg_ |= __m;
297+ if (_FillValue)
298+ *__first.__seg_ |= __m;
299+ else
300+ *__first.__seg_ &= ~__m;
389301 __n -= __dn;
390302 ++__first.__seg_ ;
391303 }
392304 // do middle whole words
393305 __storage_type __nw = __n / __bits_per_word;
394- // __storage_type is always an unsigned type, so -1 sets all bits
395- std::fill_n (std::__to_address (__first.__seg_ ), __nw, static_cast <__storage_type>(-1 ));
306+ std::fill_n (std::__to_address (__first.__seg_ ), __nw, _FillValue ? static_cast <__storage_type>(-1 ) : 0 );
396307 __n -= __nw * __bits_per_word;
397308 // do last partial word
398309 if (__n > 0 )
399310 {
400311 __first.__seg_ += __nw;
401312 __storage_type __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
402- *__first.__seg_ |= __m;
313+ if (_FillValue)
314+ *__first.__seg_ |= __m;
315+ else
316+ *__first.__seg_ &= ~__m;
403317 }
404318}
405319
@@ -411,9 +325,9 @@ fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __v
411325 if (__n > 0 )
412326 {
413327 if (__value)
414- _VSTD::__fill_n_true (__first, __n);
328+ _VSTD::__fill_n< true > (__first, __n);
415329 else
416- _VSTD::__fill_n_false (__first, __n);
330+ _VSTD::__fill_n< false > (__first, __n);
417331 }
418332}
419333
@@ -1276,13 +1190,9 @@ private:
12761190 friend class __bit_const_reference <_Cp>;
12771191 friend class __bit_iterator <_Cp, true >;
12781192 template <class _Dp > friend struct __bit_array ;
1279- template <class _Dp >
1193+ template <bool _FillValue, class _Dp >
12801194 _LIBCPP_CONSTEXPR_SINCE_CXX20
1281- friend void __fill_n_false (__bit_iterator<_Dp, false > __first, typename _Dp::size_type __n);
1282-
1283- template <class _Dp >
1284- _LIBCPP_CONSTEXPR_SINCE_CXX20
1285- friend void __fill_n_true (__bit_iterator<_Dp, false > __first, typename _Dp::size_type __n);
1195+ friend void __fill_n (__bit_iterator<_Dp, false > __first, typename _Dp::size_type __n);
12861196
12871197 template <class _Dp , bool _IC>
12881198 _LIBCPP_CONSTEXPR_SINCE_CXX20
@@ -1343,17 +1253,12 @@ private:
13431253 friend bool equal (__bit_iterator<_Dp, _IC1>,
13441254 __bit_iterator<_Dp, _IC1>,
13451255 __bit_iterator<_Dp, _IC2>);
1346- template <class _Dp , bool _IC>
1347- _LIBCPP_CONSTEXPR_SINCE_CXX20
1348- friend __bit_iterator<_Dp, _IC> __find_bool_true (__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1349- template <class _Dp , bool _IC>
1256+ template <bool _ToFind, class _Dp , bool _IC>
13501257 _LIBCPP_CONSTEXPR_SINCE_CXX20
1351- friend __bit_iterator<_Dp, _IC> __find_bool_false (__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1352- template <class _Dp , bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1258+ friend __bit_iterator<_Dp, _IC> __find_bool (__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1259+ template <bool _ToCount, class _Dp , bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
13531260 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
1354- __count_bool_true (__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1355- template <class _Dp , bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1356- __count_bool_false (__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1261+ __count_bool (__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
13571262};
13581263
13591264_LIBCPP_END_NAMESPACE_STD
0 commit comments