use std::ops::{BitAnd, BitOr};
use roaring::RoaringBitmap;
#[derive(Clone, Debug, PartialEq)]
pub enum SignedRoaringBitmap {
Include(RoaringBitmap),
Exclude(RoaringBitmap),
}
impl SignedRoaringBitmap {
pub fn empty() -> Self {
Self::Include(RoaringBitmap::new())
}
pub fn full() -> Self {
Self::Exclude(RoaringBitmap::new())
}
pub fn contains(&self, value: u32) -> bool {
use SignedRoaringBitmap::*;
match self {
Include(rbm) => rbm.contains(value),
Exclude(rbm) => !rbm.contains(value),
}
}
pub fn flip(self) -> Self {
use SignedRoaringBitmap::*;
match self {
Include(rbm) => Exclude(rbm),
Exclude(rbm) => Include(rbm),
}
}
}
impl BitAnd for SignedRoaringBitmap {
type Output = Self;
fn bitand(self, rhs: Self) -> Self {
use SignedRoaringBitmap::*;
match (self, rhs) {
(Include(lhs), Include(rhs)) => Include(lhs & rhs),
(Include(lhs), Exclude(rhs)) => Include(lhs - rhs),
(Exclude(lhs), Include(rhs)) => Include(rhs - lhs),
(Exclude(lhs), Exclude(rhs)) => Exclude(lhs | rhs),
}
}
}
impl BitOr for SignedRoaringBitmap {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
use SignedRoaringBitmap::*;
match (self, rhs) {
(Include(lhs), Include(rhs)) => Include(lhs | rhs),
(Include(lhs), Exclude(rhs)) => Exclude(rhs - lhs),
(Exclude(lhs), Include(rhs)) => Exclude(lhs - rhs),
(Exclude(lhs), Exclude(rhs)) => Exclude(lhs & rhs),
}
}
}