Skip to content

Commit e8b4c84

Browse files
committed
Auto merge of #24890 - jooert:bitvec-append-split_off, r=alexcrichton
cc #19986 r? @gankro
2 parents 8767e97 + d55a7e8 commit e8b4c84

File tree

3 files changed

+237
-0
lines changed

3 files changed

+237
-0
lines changed

src/libcollections/bit.rs

+101
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};
@@ -602,6 +603,106 @@ impl BitVec {
602603
Iter { bit_vec: self, next_idx: 0, end_idx: self.nbits }
603604
}
604605

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

src/libcollectionstest/bit/vec.rs

+135
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;

src/libcollectionstest/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(bit_vec_append_split_off)]
1112
#![feature(box_syntax)]
1213
#![feature(collections)]
1314
#![feature(collections_drain)]

0 commit comments

Comments
 (0)