2018-07-30 07:15:37 -07:00
|
|
|
/// The empty set of boolean values.
|
2018-07-31 00:38:52 -07:00
|
|
|
pub const NONE: BoolSet = BoolSet(0b00);
|
2018-05-24 10:52:58 -07:00
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
/// The set containing only `false`.
|
2018-07-31 00:38:52 -07:00
|
|
|
pub const FALSE: BoolSet = BoolSet(0b01);
|
2018-05-24 10:52:58 -07:00
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
/// The set containing only `true`.
|
2018-07-31 00:38:52 -07:00
|
|
|
pub const TRUE: BoolSet = BoolSet(0b10);
|
2018-05-24 10:52:58 -07:00
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
/// The set of both boolean values, `false` and `true`.
|
2018-07-31 00:38:52 -07:00
|
|
|
pub const BOTH: BoolSet = BoolSet(0b11);
|
2018-05-24 10:52:58 -07:00
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
/// A set of `bool` values, represented as a single byte in memory.
|
|
|
|
#[derive(
|
|
|
|
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Rand, Default,
|
|
|
|
)]
|
2018-07-31 00:38:52 -07:00
|
|
|
pub struct BoolSet(u8);
|
2018-05-24 10:52:58 -07:00
|
|
|
|
2018-07-31 00:38:52 -07:00
|
|
|
impl BoolSet {
|
|
|
|
/// Inserts a boolean value into the `BoolSet` and returns `true` iff the `BoolSet` has
|
2018-05-24 10:52:58 -07:00
|
|
|
/// changed as a result.
|
|
|
|
pub fn insert(&mut self, b: bool) -> bool {
|
2018-07-30 07:15:37 -07:00
|
|
|
let prev = *self;
|
|
|
|
self.0 |= Self::from(b).0;
|
|
|
|
prev != *self
|
2018-05-24 10:52:58 -07:00
|
|
|
}
|
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
/// Removes a value from the set.
|
|
|
|
pub fn remove(&mut self, b: bool) {
|
|
|
|
self.0 &= Self::from(!b).0;
|
2018-05-24 10:52:58 -07:00
|
|
|
}
|
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
/// Returns `true` if the set contains the value `b`.
|
2018-07-13 01:52:44 -07:00
|
|
|
pub fn contains(self, b: bool) -> bool {
|
2018-07-30 07:15:37 -07:00
|
|
|
self.0 & Self::from(b).0 != 0
|
2018-05-24 10:52:58 -07:00
|
|
|
}
|
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
/// Returns `true` if every element of `self` is also an element of `other`.
|
2018-07-31 00:38:52 -07:00
|
|
|
pub fn is_subset(self, other: BoolSet) -> bool {
|
2018-07-30 07:15:37 -07:00
|
|
|
self.0 & other.0 == self.0
|
2018-05-24 10:52:58 -07:00
|
|
|
}
|
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
/// Returns `Some(b)` if the set is the singleton with the value `b`, otherwise `None`.
|
2018-07-13 01:52:44 -07:00
|
|
|
pub fn definite(self) -> Option<bool> {
|
2018-05-24 10:52:58 -07:00
|
|
|
match self {
|
2018-07-30 07:15:37 -07:00
|
|
|
FALSE => Some(false),
|
|
|
|
TRUE => Some(true),
|
2018-05-24 10:52:58 -07:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-31 00:38:52 -07:00
|
|
|
impl From<bool> for BoolSet {
|
2018-07-30 07:15:37 -07:00
|
|
|
fn from(b: bool) -> Self {
|
|
|
|
if b {
|
|
|
|
TRUE
|
|
|
|
} else {
|
|
|
|
FALSE
|
|
|
|
}
|
2018-05-24 10:52:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-31 00:38:52 -07:00
|
|
|
/// An iterator over a `BoolSet`.
|
2018-07-30 07:15:37 -07:00
|
|
|
#[derive(Clone, Copy, Debug)]
|
2018-07-31 00:38:52 -07:00
|
|
|
pub struct BoolSetIter(BoolSet);
|
2018-05-24 10:52:58 -07:00
|
|
|
|
2018-07-31 00:38:52 -07:00
|
|
|
impl Iterator for BoolSetIter {
|
2018-07-30 07:15:37 -07:00
|
|
|
type Item = bool;
|
2018-05-24 10:52:58 -07:00
|
|
|
|
2018-07-30 07:15:37 -07:00
|
|
|
fn next(&mut self) -> Option<bool> {
|
|
|
|
if self.0.contains(true) {
|
|
|
|
self.0.remove(true);
|
|
|
|
Some(true)
|
|
|
|
} else if self.0.contains(false) {
|
|
|
|
self.0.remove(false);
|
|
|
|
Some(false)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2018-05-24 10:52:58 -07:00
|
|
|
}
|
|
|
|
}
|
2018-07-28 08:31:17 -07:00
|
|
|
|
2018-07-31 00:38:52 -07:00
|
|
|
impl IntoIterator for BoolSet {
|
2018-07-30 07:15:37 -07:00
|
|
|
type Item = bool;
|
2018-07-31 00:38:52 -07:00
|
|
|
type IntoIter = BoolSetIter;
|
2018-07-28 08:31:17 -07:00
|
|
|
|
2018-07-30 04:08:17 -07:00
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
2018-07-31 00:38:52 -07:00
|
|
|
BoolSetIter(self)
|
2018-07-28 08:31:17 -07:00
|
|
|
}
|
|
|
|
}
|