Skip to content

Commit 5b1c801

Browse files
committed
Implement append and split_off for BitVec (RFC 509)
1 parent da2276e commit 5b1c801

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed

src/libcollections/bit.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ use core::hash;
8989
use core::iter::RandomAccessIterator;
9090
use core::iter::{Chain, Enumerate, Repeat, Skip, Take, repeat, Cloned};
9191
use core::iter::{self, FromIterator};
92+
use core::mem::swap;
9293
use core::ops::Index;
9394
use core::slice;
9495
use core::{u8, u32, usize};
@@ -604,6 +605,110 @@ impl BitVec {
604605
Iter { bit_vec: self, next_idx: 0, end_idx: self.nbits }
605606
}
606607

608+
/// Moves all bits from `other` into `Self`, leaving `other` empty.
609+
///
610+
/// # Examples
611+
///
612+
/// ```
613+
/// # #![feature(collections)]
614+
/// use std::collections::BitVec;
615+
///
616+
/// let mut a = BitVec::new();
617+
/// a.push(true);
618+
/// a.push(false);
619+
///
620+
/// let mut b = BitVec::new();
621+
/// b.push(false);
622+
/// b.push(true);
623+
/// b.push(true);
624+
///
625+
/// a.append(&mut b);
626+
///
627+
/// assert_eq!(a.len(), 5);
628+
/// assert_eq!(b.len(), 0);
629+
/// assert!(a.eq_vec(&[true, false, false, true, true]));
630+
/// ```
631+
#[unstable(feature = "collections",
632+
reason = "recently added as part of collections reform 2")]
633+
pub fn append(&mut self, other: &mut Self) {
634+
let b = self.len() % u32::BITS;
635+
636+
self.nbits += other.len();
637+
other.nbits = 0;
638+
639+
if b == 0 {
640+
self.storage.append(&mut other.storage);
641+
} else {
642+
self.storage.reserve(other.storage.len());
643+
644+
for block in other.storage.drain() {
645+
*(self.storage.last_mut().unwrap()) += block << b;
646+
self.storage.push(block >> (u32::BITS - b));
647+
}
648+
}
649+
}
650+
651+
/// Splits the `BitVec` into two at the given bit.
652+
///
653+
/// # Examples
654+
///
655+
/// ```
656+
/// # #![feature(collections)]
657+
/// use std::collections::BitVec;
658+
/// let mut a = BitVec::new();
659+
/// a.push(true);
660+
/// a.push(false);
661+
/// a.push(false);
662+
/// a.push(true);
663+
///
664+
/// let b = a.split_off(2);
665+
///
666+
/// assert_eq!(a.len(), 2);
667+
/// assert_eq!(b.len(), 2);
668+
/// assert!(a.eq_vec(&[true, false]));
669+
/// assert!(b.eq_vec(&[false, true]));
670+
/// ```
671+
#[unstable(feature = "collections",
672+
reason = "recently added as part of collections reform 2")]
673+
pub fn split_off(&mut self, at: usize) -> Self {
674+
let mut other = BitVec::new();
675+
676+
if at == 0 {
677+
swap(self, &mut other);
678+
return other;
679+
} else if at > self.len() {
680+
return other;
681+
}
682+
683+
let w = at / u32::BITS;
684+
let b = at % u32::BITS;
685+
other.nbits = self.nbits - at;
686+
self.nbits = at;
687+
if b == 0 {
688+
// Split at block boundary
689+
other.storage = self.storage.split_off(w);
690+
return other;
691+
} else {
692+
other.storage.reserve(self.storage.len() - w);
693+
694+
{
695+
let mut cur = self.storage.iter().skip(w).peekable();
696+
loop {
697+
match (cur.next(), cur.peek()) {
698+
(Some(x), Some(y)) => { other.storage.push((*x >> b) + (**y << (u32::BITS - b))) },
699+
(Some(x), None) => { other.storage.push((*x >> b)); break; },
700+
(None, Some(_)) => unreachable!(),
701+
(None, None) => unreachable!(),
702+
}
703+
}
704+
}
705+
706+
self.storage.truncate(w+1);
707+
}
708+
709+
other
710+
}
711+
607712
/// Returns `true` if all bits are 0.
608713
///
609714
/// # Examples

src/libcollectionstest/bit/vec.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,109 @@ fn test_bit_vec_extend() {
630630
0b01001001, 0b10010010, 0b10111101]));
631631
}
632632

633+
#[test]
634+
fn test_bit_vec_append() {
635+
// Append to BitVec, that holds a multiple of u32::BITS bits
636+
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011]);
637+
let mut b = BitVec::new();
638+
b.push(false);
639+
b.push(true);
640+
b.push(true);
641+
642+
a.append(&mut b);
643+
644+
assert_eq!(a.len(), 35);
645+
assert_eq!(b.len(), 0);
646+
assert!(b.capacity() >= 3);
647+
648+
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
649+
false, false, false, true, false, false, true, false,
650+
true, false, false, true, false, false, true, false,
651+
false, false, true, true, false, false, true, true,
652+
false, true, true]));
653+
654+
// Append to arbitrary BitVec
655+
let mut a = BitVec::new();
656+
a.push(true);
657+
a.push(false);
658+
659+
let mut b = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
660+
661+
a.append(&mut b);
662+
663+
assert_eq!(a.len(), 42);
664+
assert_eq!(b.len(), 0);
665+
assert!(b.capacity() >= 40);
666+
667+
assert!(a.eq_vec(&[true, false, true, false, true, false, false, false,
668+
false, false, false, false, false, true, false, false,
669+
true, false, true, false, false, true, false, false,
670+
true, false, false, false, true, true, false, false,
671+
true, true, true, false, false, true, false, true,
672+
false, true]));
673+
}
674+
675+
#[test]
676+
fn test_bit_vec_split_off() {
677+
// Split at 0
678+
let mut a = BitVec::new();
679+
a.push(true);
680+
a.push(false);
681+
a.push(false);
682+
a.push(true);
683+
684+
let b = a.split_off(0);
685+
686+
assert_eq!(a.len(), 0);
687+
assert_eq!(b.len(), 4);
688+
689+
assert!(b.eq_vec(&[true, false, false, true]));
690+
691+
// Split behind last bit
692+
a.truncate(0);
693+
a.push(true);
694+
a.push(false);
695+
a.push(false);
696+
a.push(true);
697+
698+
let b = a.split_off(5);
699+
700+
assert_eq!(a.len(), 4);
701+
assert_eq!(b.len(), 0);
702+
703+
assert!(a.eq_vec(&[true, false, false, true]));
704+
705+
// Split at block boundary
706+
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b11110011]);
707+
708+
let b = a.split_off(32);
709+
710+
assert_eq!(a.len(), 32);
711+
assert_eq!(b.len(), 8);
712+
713+
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
714+
false, false, false, true, false, false, true, false,
715+
true, false, false, true, false, false, true, false,
716+
false, false, true, true, false, false, true, true]));
717+
assert!(b.eq_vec(&[true, true, true, true, false, false, true, true]));
718+
719+
// Don't split at block boundary
720+
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b01101011, 0b10101101]);
721+
722+
let b = a.split_off(13);
723+
724+
assert_eq!(a.len(), 13);
725+
assert_eq!(b.len(), 35);
726+
727+
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
728+
false, false, false, true, false]));
729+
assert!(b.eq_vec(&[false, true, false, true, false, false, true, false,
730+
false, true, false, false, false, true, true, false,
731+
false, true, true, false, true, true, false, true,
732+
false, true, true, true, false, true, false, true,
733+
true, false, true]));
734+
}
735+
633736
mod bench {
634737
use std::collections::BitVec;
635738
use std::u32;

0 commit comments

Comments
 (0)