use std::mem;
use std::ops::{
BitAnd,
BitAndAssign,
BitOr,
BitOrAssign,
BitXor,
BitXorAssign,
Sub,
SubAssign
};
use std::slice::Iter;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct USizeSet {
min: usize,
max: usize,
len: usize,
content: Vec<u64>
}
#[derive(Debug, Eq, PartialEq)]
pub enum USizeSetError {
InvalidBounds,
DifferentBounds,
OutOfBounds
}
pub type USizeSetResult<V> = Result<V, USizeSetError>;
struct BitIterator {
bit_index: usize,
value: u64
}
impl BitIterator {
fn new(value: u64) -> BitIterator {
BitIterator {
bit_index: 0,
value
}
}
fn progress(&mut self) {
let diff = self.value.trailing_zeros() as usize;
self.value >>= diff;
self.bit_index += diff;
}
}
impl Iterator for BitIterator {
type Item = usize;
fn next(&mut self) -> Option<usize> {
if self.value != 0 && (self.value & 1) == 0 {
self.progress();
}
let result = if self.value == 0 { None } else { Some(self.bit_index) };
self.value &= 0xfffffffffffffffe;
result
}
}
pub struct USizeSetIter<'a> {
offset: usize,
current: BitIterator,
content: Iter<'a, u64>
}
impl<'a> USizeSetIter<'a> {
fn new(set: &'a USizeSet) -> USizeSetIter<'a> {
let mut iter = set.content.iter();
let first_bit_iterator = if let Some(&first) = iter.next() {
BitIterator::new(first)
}
else {
BitIterator::new(0)
};
USizeSetIter {
offset: set.min,
current: first_bit_iterator,
content: iter
}
}
}
const USIZE_BIT_SIZE: usize = mem::size_of::<usize>() * 8;
impl<'a> Iterator for USizeSetIter<'a> {
type Item = usize;
fn next(&mut self) -> Option<usize> {
loop {
if let Some(bit_index) = self.current.next() {
return Some(self.offset + bit_index);
}
if let Some(&next_content) = self.content.next() {
self.current = BitIterator::new(next_content);
self.offset += USIZE_BIT_SIZE;
}
else {
return None;
}
}
}
}
impl USizeSet {
pub fn new(min: usize, max: usize) -> USizeSetResult<USizeSet> {
if min > max {
Err(USizeSetError::InvalidBounds)
}
else {
let required_words = (max - min + 64) >> 6;
Ok(USizeSet {
min,
max,
len: 0,
content: vec![0u64; required_words]
})
}
}
pub fn singleton(min: usize, max: usize, content: usize)
-> USizeSetResult<USizeSet> {
let mut result = USizeSet::new(min, max)?;
result.insert(content)?;
Ok(result)
}
pub fn range(min: usize, max: usize) -> USizeSetResult<USizeSet> {
if min > max {
Err(USizeSetError::InvalidBounds)
}
else {
let mut content = Vec::new();
let ones = max - min + 1;
let ones_words = ones >> 6;
for _ in 1..ones_words {
content.push(!0);
}
let remaining_ones = ones - (ones_words << 6);
if remaining_ones > 0 {
content.push((1 << remaining_ones) - 1);
}
Ok(USizeSet {
min,
max,
len: ones,
content
})
}
}
fn compute_index(&self, number: usize) -> USizeSetResult<(usize, u64)> {
if number < self.min || number > self.max {
Err(USizeSetError::OutOfBounds)
}
else {
let index = number - self.min;
let word_index = index >> 6;
let sub_word_index = index & 63;
let mask = 1u64 << sub_word_index;
Ok((word_index, mask))
}
}
pub fn min(&self) -> usize {
self.min
}
pub fn max(&self) -> usize {
self.max
}
pub fn contains(&self, number: usize) -> bool {
if let Ok((word_index, mask)) = self.compute_index(number) {
(self.content[word_index] & mask) > 0
}
else {
false
}
}
pub fn insert(&mut self, number: usize) -> USizeSetResult<bool> {
let (word_index, mask) = self.compute_index(number)?;
let word = &mut self.content[word_index];
if *word & mask == 0 {
self.len += 1;
*word |= mask;
Ok(true)
}
else {
Ok(false)
}
}
pub fn remove(&mut self, number: usize) -> USizeSetResult<bool> {
let (word_index, mask) = self.compute_index(number)?;
let word = &mut self.content[word_index];
if *word & mask > 0 {
*word &= !mask;
self.len -= 1;
Ok(true)
}
else {
Ok(false)
}
}
pub fn clear(&mut self) {
for i in 0..self.content.len() {
self.content[i] = 0;
}
self.len = 0;
}
pub fn iter(&self) -> USizeSetIter<'_> {
USizeSetIter::new(self)
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn len(&self) -> usize {
self.len
}
fn count(&self) -> usize {
self.content.iter()
.map(|c| c.count_ones() as usize)
.sum()
}
fn op_assign(&mut self, other: &USizeSet, op: impl Fn(u64, u64) -> u64)
-> USizeSetResult<bool> {
if self.min() != other.min() || self.max() != other.max() {
Err(USizeSetError::DifferentBounds)
}
else {
let contents = self.content.iter_mut().zip(other.content.iter());
let mut changed = false;
for (self_u64, &other_u64) in contents {
let self_before = *self_u64;
*self_u64 = op(self_before, other_u64);
changed |= self_before != *self_u64;
}
self.len = self.count();
Ok(changed)
}
}
fn op(&self, other: &USizeSet,
op_assign: impl Fn(&mut USizeSet, &USizeSet) -> USizeSetResult<bool>)
-> USizeSetResult<USizeSet> {
let mut clone = self.clone();
op_assign(&mut clone, other)?;
Ok(clone)
}
pub fn union_assign(&mut self, other: &USizeSet) -> USizeSetResult<bool> {
self.op_assign(other, u64::bitor)
}
pub fn union(&self, other: &USizeSet) -> USizeSetResult<USizeSet> {
self.op(other, USizeSet::union_assign)
}
pub fn intersect_assign(&mut self, other: &USizeSet)
-> USizeSetResult<bool> {
self.op_assign(other, u64::bitand)
}
pub fn intersect(&self, other: &USizeSet) -> USizeSetResult<USizeSet> {
self.op(other, USizeSet::intersect_assign)
}
pub fn difference_assign(&mut self, other: &USizeSet)
-> USizeSetResult<bool> {
self.op_assign(other, |a, b| a & !b)
}
pub fn difference(&self, other: &USizeSet) -> USizeSetResult<USizeSet> {
self.op(other, USizeSet::difference_assign)
}
pub fn symmetric_difference_assign(&mut self, other: &USizeSet)
-> USizeSetResult<bool> {
self.op_assign(other, u64::bitxor)
}
pub fn symmetric_difference(&self, other: &USizeSet)
-> USizeSetResult<USizeSet> {
self.op(other, USizeSet::symmetric_difference_assign)
}
}
#[macro_export]
macro_rules! set {
($set:expr; $e:expr) => {
($set).insert($e).unwrap()
};
($set:expr; $e:expr, $($es:expr),+) => {
set!($set; $e);
set!($set; $($es),+)
};
($min:expr, $max:expr; $($es:expr),+) => {
{
let mut set = USizeSet::new($min, $max).unwrap();
set!(set; $($es),+);
set
}
};
}
impl BitAnd<&USizeSet> for USizeSet {
type Output = USizeSet;
fn bitand(mut self, rhs: &USizeSet) -> USizeSet {
self.intersect_assign(rhs).unwrap();
self
}
}
impl BitOr<&USizeSet> for USizeSet {
type Output = USizeSet;
fn bitor(mut self, rhs: &USizeSet) -> USizeSet {
self.union_assign(rhs).unwrap();
self
}
}
impl Sub<&USizeSet> for USizeSet {
type Output = USizeSet;
fn sub(mut self, rhs: &USizeSet) -> USizeSet {
self.difference_assign(rhs).unwrap();
self
}
}
impl BitXor<&USizeSet> for USizeSet {
type Output = USizeSet;
fn bitxor(mut self, rhs: &USizeSet) -> USizeSet {
self.symmetric_difference_assign(rhs).unwrap();
self
}
}
impl BitAnd for &USizeSet {
type Output = USizeSet;
fn bitand(self, rhs: &USizeSet) -> USizeSet {
self.intersect(rhs).unwrap()
}
}
impl BitOr for &USizeSet {
type Output = USizeSet;
fn bitor(self, rhs: &USizeSet) -> USizeSet {
self.union(rhs).unwrap()
}
}
impl Sub for &USizeSet {
type Output = USizeSet;
fn sub(self, rhs: &USizeSet) -> USizeSet {
self.difference(rhs).unwrap()
}
}
impl BitXor for &USizeSet {
type Output = USizeSet;
fn bitxor(self, rhs: &USizeSet) -> USizeSet {
self.symmetric_difference(rhs).unwrap()
}
}
impl BitAndAssign<&USizeSet> for USizeSet {
fn bitand_assign(&mut self, rhs: &USizeSet) {
self.intersect_assign(rhs).unwrap();
}
}
impl BitOrAssign<&USizeSet> for USizeSet {
fn bitor_assign(&mut self, rhs: &USizeSet) {
self.union_assign(rhs).unwrap();
}
}
impl SubAssign<&USizeSet> for USizeSet {
fn sub_assign(&mut self, rhs: &USizeSet) {
self.difference_assign(rhs).unwrap();
}
}
impl BitXorAssign<&USizeSet> for USizeSet {
fn bitxor_assign(&mut self, rhs: &USizeSet) {
self.symmetric_difference_assign(rhs).unwrap();
}
}
impl BitAndAssign<&USizeSet> for &mut USizeSet {
fn bitand_assign(&mut self, rhs: &USizeSet) {
self.intersect_assign(rhs).unwrap();
}
}
impl BitOrAssign<&USizeSet> for &mut USizeSet {
fn bitor_assign(&mut self, rhs: &USizeSet) {
self.union_assign(rhs).unwrap();
}
}
impl SubAssign<&USizeSet> for &mut USizeSet {
fn sub_assign(&mut self, rhs: &USizeSet) {
self.difference_assign(rhs).unwrap();
}
}
impl BitXorAssign<&USizeSet> for &mut USizeSet {
fn bitxor_assign(&mut self, rhs: &USizeSet) {
self.symmetric_difference_assign(rhs).unwrap();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_set_is_empty() {
let set = USizeSet::new(1, 9).unwrap();
assert!(set.is_empty());
assert!(!set.contains(1));
assert!(!set.contains(3));
assert!(!set.contains(9));
assert_eq!(0, set.len());
}
#[test]
fn range_set_is_full() {
let set = USizeSet::range(1, 9).unwrap();
assert!(!set.is_empty());
assert!(set.contains(1));
assert!(set.contains(3));
assert!(set.contains(9));
assert_eq!(9, set.len());
}
#[test]
fn singleton_set_contains_only_given_element() {
let set = USizeSet::singleton(1, 9, 3).unwrap();
assert!(!set.is_empty());
assert!(!set.contains(1));
assert!(set.contains(3));
assert!(!set.contains(9));
assert_eq!(1, set.len());
}
#[test]
fn set_macro_has_specified_range() {
let set = set!(2, 5; 3);
assert_eq!(2, set.min());
assert_eq!(5, set.max());
}
#[test]
fn set_macro_contains_specified_elements() {
let set = set!(2, 8; 3, 7, 8);
assert_eq!(3, set.len());
assert!(set.contains(3));
assert!(set.contains(7));
assert!(set.contains(8));
assert!(!set.contains(5));
}
#[test]
fn set_creation_error() {
assert_eq!(Err(USizeSetError::InvalidBounds), USizeSet::new(1, 0));
assert_eq!(Err(USizeSetError::InvalidBounds), USizeSet::new(5, 3));
}
#[test]
fn set_insertion_error() {
let mut set = USizeSet::new(1, 5).unwrap();
assert_eq!(Err(USizeSetError::OutOfBounds), set.insert(0));
assert_eq!(Err(USizeSetError::OutOfBounds), set.insert(6));
}
#[test]
fn set_operation_error() {
let set_1 = USizeSet::new(1, 9).unwrap();
let set_2 = USizeSet::new(1, 6).unwrap();
assert_eq!(Err(USizeSetError::DifferentBounds), set_1.union(&set_2));
assert_eq!(Err(USizeSetError::DifferentBounds),
set_2.intersect(&set_1));
}
#[test]
fn manipulation() {
let mut set = USizeSet::new(1, 9).unwrap();
set.insert(2).unwrap();
set.insert(4).unwrap();
set.insert(6).unwrap();
assert!(!set.is_empty());
assert!(set.contains(2));
assert!(set.contains(4));
assert!(set.contains(6));
assert_eq!(3, set.len());
set.remove(4).unwrap();
assert!(!set.is_empty());
assert!(set.contains(2));
assert!(!set.contains(4));
assert!(set.contains(6));
assert_eq!(2, set.len());
set.clear();
assert!(set.is_empty());
assert!(!set.contains(2));
assert!(!set.contains(4));
assert!(!set.contains(6));
assert_eq!(0, set.len());
}
#[test]
fn iteration() {
let mut set = USizeSet::new(1, 100).unwrap();
set.insert(1).unwrap();
set.insert(12).unwrap();
set.insert(23).unwrap();
set.insert(36).unwrap();
set.insert(42).unwrap();
set.insert(64).unwrap();
set.insert(65).unwrap();
set.insert(97).unwrap();
set.insert(100).unwrap();
let mut iter = set.iter();
assert_eq!(Some(1), iter.next());
assert_eq!(Some(12), iter.next());
assert_eq!(Some(23), iter.next());
assert_eq!(Some(36), iter.next());
assert_eq!(Some(42), iter.next());
assert_eq!(Some(64), iter.next());
assert_eq!(Some(65), iter.next());
assert_eq!(Some(97), iter.next());
assert_eq!(Some(100), iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn double_insert() {
let mut set = USizeSet::new(1, 9).unwrap();
assert!(set.insert(3).unwrap());
assert!(set.insert(4).unwrap());
assert!(!set.insert(3).unwrap());
assert!(set.contains(3));
assert_eq!(2, set.len());
}
#[test]
fn double_remove() {
let mut set = USizeSet::range(1, 9).unwrap();
assert!(set.remove(3).unwrap());
assert!(set.remove(5).unwrap());
assert!(!set.remove(3).unwrap());
assert!(!set.contains(3));
assert_eq!(7, set.len());
}
fn op_test_lhs() -> USizeSet {
set!(1, 4; 2, 4)
}
fn op_test_rhs() -> USizeSet {
set!(1, 4; 3, 4)
}
#[test]
fn union() {
let result = op_test_lhs() | &op_test_rhs();
let expected = set!(1, 4; 2, 3, 4);
assert_eq!(expected, result);
}
#[test]
fn intersection() {
let result = op_test_lhs() & &op_test_rhs();
let expected = set!(1, 4; 4);
assert_eq!(expected, result);
}
#[test]
fn difference() {
let result = op_test_lhs() - &op_test_rhs();
let expected = set!(1, 4; 2);
assert_eq!(expected, result);
}
#[test]
fn symmetric_difference() {
let result = op_test_lhs() ^ &op_test_rhs();
let expected = set!(1, 4; 2, 3);
assert_eq!(expected, result);
}
}