Skip to content

Commit 7311394

Browse files
committed
Implement append and split_off for BitVec (RFC 509)
1 parent 551a74d commit 7311394

File tree

2 files changed

+235
-0
lines changed

2 files changed

+235
-0
lines changed

src/libcollections/bit.rs

Lines changed: 100 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,105 @@ 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::from_bytes(&[0b10000000]);
617+
/// let mut b = BitVec::from_bytes(&[0b01100001]);
618+
///
619+
/// a.append(&mut b);
620+
///
621+
/// assert_eq!(a.len(), 16);
622+
/// assert_eq!(b.len(), 0);
623+
/// assert!(a.eq_vec(&[true, false, false, false, false, false, false, false,
624+
/// false, true, true, false, false, false, false, true]));
625+
/// ```
626+
#[unstable(feature = "bit_vec_append_split_off",
627+
reason = "recently added as part of collections reform 2")]
628+
pub fn append(&mut self, other: &mut Self) {
629+
let b = self.len() % u32::BITS;
630+
631+
self.nbits += other.len();
632+
other.nbits = 0;
633+
634+
if b == 0 {
635+
self.storage.append(&mut other.storage);
636+
} else {
637+
self.storage.reserve(other.storage.len());
638+
639+
for block in other.storage.drain() {
640+
*(self.storage.last_mut().unwrap()) |= block << b;
641+
self.storage.push(block >> (u32::BITS - b));
642+
}
643+
}
644+
}
645+
646+
/// Splits the `BitVec` into two at the given bit.
647+
///
648+
/// # Examples
649+
///
650+
/// ```
651+
/// # #![feature(collections)]
652+
/// use std::collections::BitVec;
653+
/// let mut a = BitVec::new();
654+
/// a.push(true);
655+
/// a.push(false);
656+
/// a.push(false);
657+
/// a.push(true);
658+
///
659+
/// let b = a.split_off(2);
660+
///
661+
/// assert_eq!(a.len(), 2);
662+
/// assert_eq!(b.len(), 2);
663+
/// assert!(a.eq_vec(&[true, false]));
664+
/// assert!(b.eq_vec(&[false, true]));
665+
/// ```
666+
#[unstable(feature = "bit_vec_append_split_off",
667+
reason = "recently added as part of collections reform 2")]
668+
pub fn split_off(&mut self, at: usize) -> Self {
669+
assert!(at <= self.len(), "`at` out of bounds");
670+
671+
let mut other = BitVec::new();
672+
673+
if at == 0 {
674+
swap(self, &mut other);
675+
return other;
676+
} else if at == self.len() {
677+
return other;
678+
}
679+
680+
let w = at / u32::BITS;
681+
let b = at % u32::BITS;
682+
other.nbits = self.nbits - at;
683+
self.nbits = at;
684+
if b == 0 {
685+
// Split at block boundary
686+
other.storage = self.storage.split_off(w);
687+
} else {
688+
other.storage.reserve(self.storage.len() - w);
689+
690+
{
691+
let mut iter = self.storage[w..].iter();
692+
let mut last = *iter.next().unwrap();
693+
for &cur in iter {
694+
other.storage.push((last >> b) | (cur << (u32::BITS - b)));
695+
last = cur;
696+
}
697+
other.storage.push(last >> b);
698+
}
699+
700+
self.storage.truncate(w+1);
701+
self.fix_last_block();
702+
}
703+
704+
other
705+
}
706+
607707
/// Returns `true` if all bits are 0.
608708
///
609709
/// # Examples

src/libcollectionstest/bit/vec.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,141 @@ 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+
// Append to empty BitVec
675+
let mut a = BitVec::new();
676+
let mut b = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
677+
678+
a.append(&mut b);
679+
680+
assert_eq!(a.len(), 40);
681+
assert_eq!(b.len(), 0);
682+
assert!(b.capacity() >= 40);
683+
684+
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
685+
false, false, false, true, false, false, true, false,
686+
true, false, false, true, false, false, true, false,
687+
false, false, true, true, false, false, true, true,
688+
true, false, false, true, false, true, false, true]));
689+
690+
// Append empty BitVec
691+
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]);
692+
let mut b = BitVec::new();
693+
694+
a.append(&mut b);
695+
696+
assert_eq!(a.len(), 40);
697+
assert_eq!(b.len(), 0);
698+
699+
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
700+
false, false, false, true, false, false, true, false,
701+
true, false, false, true, false, false, true, false,
702+
false, false, true, true, false, false, true, true,
703+
true, false, false, true, false, true, false, true]));
704+
}
705+
706+
#[test]
707+
fn test_bit_vec_split_off() {
708+
// Split at 0
709+
let mut a = BitVec::new();
710+
a.push(true);
711+
a.push(false);
712+
a.push(false);
713+
a.push(true);
714+
715+
let b = a.split_off(0);
716+
717+
assert_eq!(a.len(), 0);
718+
assert_eq!(b.len(), 4);
719+
720+
assert!(b.eq_vec(&[true, false, false, true]));
721+
722+
// Split at last bit
723+
a.truncate(0);
724+
a.push(true);
725+
a.push(false);
726+
a.push(false);
727+
a.push(true);
728+
729+
let b = a.split_off(4);
730+
731+
assert_eq!(a.len(), 4);
732+
assert_eq!(b.len(), 0);
733+
734+
assert!(a.eq_vec(&[true, false, false, true]));
735+
736+
// Split at block boundary
737+
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b11110011]);
738+
739+
let b = a.split_off(32);
740+
741+
assert_eq!(a.len(), 32);
742+
assert_eq!(b.len(), 8);
743+
744+
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
745+
false, false, false, true, false, false, true, false,
746+
true, false, false, true, false, false, true, false,
747+
false, false, true, true, false, false, true, true]));
748+
assert!(b.eq_vec(&[true, true, true, true, false, false, true, true]));
749+
750+
// Don't split at block boundary
751+
let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011,
752+
0b01101011, 0b10101101]);
753+
754+
let b = a.split_off(13);
755+
756+
assert_eq!(a.len(), 13);
757+
assert_eq!(b.len(), 35);
758+
759+
assert!(a.eq_vec(&[true, false, true, false, false, false, false, false,
760+
false, false, false, true, false]));
761+
assert!(b.eq_vec(&[false, true, false, true, false, false, true, false,
762+
false, true, false, false, false, true, true, false,
763+
false, true, true, false, true, true, false, true,
764+
false, true, true, true, false, true, false, true,
765+
true, false, true]));
766+
}
767+
633768
mod bench {
634769
use std::collections::BitVec;
635770
use std::u32;

0 commit comments

Comments
 (0)