@@ -72,6 +72,11 @@ impl BitBufferMut {
7272 }
7373 }
7474
75+ /// Consumes the buffer and return the underlying byte buffer.
76+ pub fn into_inner ( self ) -> ByteBufferMut {
77+ self . buffer
78+ }
79+
7580 /// Create a new mutable buffer with requested `len` and all bits set to `true`.
7681 pub fn new_set ( len : usize ) -> Self {
7782 Self {
@@ -205,20 +210,24 @@ impl BitBufferMut {
205210
206211 /// Set the bit at `index` to `true` without checking bounds.
207212 ///
213+ /// Note: Do not call this in a tight loop. Prefer to use [`set_bit_unchecked`].
214+ ///
208215 /// # Safety
209216 ///
210217 /// The caller must ensure that `index` does not exceed the largest bit index in the backing buffer.
211- pub unsafe fn set_unchecked ( & mut self , index : usize ) {
218+ unsafe fn set_unchecked ( & mut self , index : usize ) {
212219 // SAFETY: checked by caller
213220 unsafe { set_bit_unchecked ( self . buffer . as_mut_ptr ( ) , self . offset + index) }
214221 }
215222
216223 /// Unset the bit at `index` without checking bounds.
217224 ///
225+ /// Note: Do not call this in a tight loop. Prefer to use [`unset_bit_unchecked`].
226+ ///
218227 /// # Safety
219228 ///
220229 /// The caller must ensure that `index` does not exceed the largest bit index in the backing buffer.
221- pub unsafe fn unset_unchecked ( & mut self , index : usize ) {
230+ unsafe fn unset_unchecked ( & mut self , index : usize ) {
222231 // SAFETY: checked by caller
223232 unsafe { unset_bit_unchecked ( self . buffer . as_mut_ptr ( ) , self . offset + index) }
224233 }
@@ -229,6 +238,7 @@ impl BitBufferMut {
229238 ///
230239 /// - `new_len` must be less than or equal to [`capacity()`](Self::capacity)
231240 /// - The elements at `old_len..new_len` must be initialized
241+ #[ inline( always) ]
232242 pub unsafe fn set_len ( & mut self , new_len : usize ) {
233243 debug_assert ! (
234244 new_len <= self . capacity( ) ,
@@ -470,6 +480,11 @@ impl BitBufferMut {
470480 pub fn as_mut_slice ( & mut self ) -> & mut [ u8 ] {
471481 self . buffer . as_mut_slice ( )
472482 }
483+
484+ /// Returns a raw mutable pointer to the internal buffer.
485+ pub fn as_mut_ptr ( & mut self ) -> * mut u8 {
486+ self . buffer . as_mut_ptr ( )
487+ }
473488}
474489
475490impl Default for BitBufferMut {
@@ -511,14 +526,20 @@ impl FromIterator<bool> for BitBufferMut {
511526 fn from_iter < T : IntoIterator < Item = bool > > ( iter : T ) -> Self {
512527 let mut iter = iter. into_iter ( ) ;
513528
514- // Note that these hints might be incorrect.
515- let ( lower_bound , upper_bound_opt ) = iter . size_hint ( ) ;
516- let capacity = upper_bound_opt . unwrap_or ( lower_bound ) ;
529+ // Since we do not know the length of the iterator, we can only guess how much memory we
530+ // need to reserve. Note that these hints may be inaccurate.
531+ let ( lower_bound , _ ) = iter . size_hint ( ) ;
517532
518- let mut buf = BitBufferMut :: new_unset ( capacity) ;
533+ // We choose not to use the optional upper bound size hint to match the standard library.
534+
535+ // Initialize all bits to 0 with the given length. By doing this, we only need to set bits
536+ // that are true (and this is faster from benchmarks).
537+ let mut buf = BitBufferMut :: new_unset ( lower_bound) ;
538+ assert_eq ! ( buf. offset, 0 ) ;
519539
520540 // Directly write within our known capacity.
521- for i in 0 ..capacity {
541+ let ptr = buf. buffer . as_mut_ptr ( ) ;
542+ for i in 0 ..lower_bound {
522543 let Some ( v) = iter. next ( ) else {
523544 // SAFETY: We are definitely under the capacity and all values are already
524545 // initialized from `new_unset`.
@@ -528,7 +549,7 @@ impl FromIterator<bool> for BitBufferMut {
528549
529550 if v {
530551 // SAFETY: We have ensured that we are within the capacity.
531- unsafe { buf . set_unchecked ( i) }
552+ unsafe { set_bit_unchecked ( ptr , i) }
532553 }
533554 }
534555
0 commit comments