use std::borrow::Borrow;
use std::default::Default;
use self::Bound::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Bound<T> {
Include(T),
Exclude(T),
Infinite,
}
impl<T> Bound<T> where T: PartialOrd + PartialEq + Clone {
#[inline]
pub fn is_finite(&self) -> bool {
match *self {
Infinite => false,
_ => true,
}
}
#[inline]
pub fn is_inclusive(&self) -> bool {
match *self {
Include(_) => true,
_ => false,
}
}
#[inline]
pub fn is_exclusive(&self) -> bool {
match *self {
Exclude(_) => true,
_ => false,
}
}
#[inline]
pub fn as_ref(&self) -> Option<&T> {
match *self {
Include(ref bound) => Some(bound),
Exclude(ref bound) => Some(bound),
Infinite => None,
}
}
#[inline]
pub fn as_mut(&mut self) -> Option<&mut T> {
match *self {
Include(ref mut bound) => Some(bound),
Exclude(ref mut bound) => Some(bound),
Infinite => None,
}
}
#[inline]
pub fn unwrap(self) -> T {
match self {
Include(x) => x,
Exclude(x) => x,
Infinite
=> panic!("called `Bound::unwrap()` on an `Infinite` value"),
}
}
#[inline]
pub fn unwrap_or(self, def: T) -> T {
match self {
Include(x) => x,
Exclude(x) => x,
Infinite => def,
}
}
#[inline]
pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
match self {
Include(x) => x,
Exclude(x) => x,
Infinite => f(),
}
}
#[inline]
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Bound<U> {
match self {
Include(x) => Include(f(x)),
Exclude(x) => Exclude(f(x)),
Infinite => Infinite,
}
}
#[inline]
pub fn map_or<U, F>(self, def: U, f: F) -> U where F: FnOnce(T) -> U {
match self {
Include(x) => f(x),
Exclude(x) => f(x),
Infinite => def,
}
}
#[inline]
pub fn map_or_else<U, D, F>(self, def: D, f: F) -> U
where
D: FnOnce() -> U,
F: FnOnce(T) -> U
{
match self {
Include(x) => f(x),
Exclude(x) => f(x),
Infinite => def(),
}
}
#[inline]
pub fn transfer<B: Borrow<Self>, O>(from: B, to: O) -> Bound<O> {
match *from.borrow() {
Include(_) => Include(to),
Exclude(_) => Exclude(to),
Infinite => Infinite,
}
}
pub(in crate) fn least_union(&self, other: &Self) -> Self {
match (self, other) {
(&Include(ref p), &Include(ref o))
=> if p < o {Include(p.clone())} else {Include(o.clone())},
(&Include(ref p), &Exclude(ref o))
=> if p <= o {Include(p.clone())} else {Exclude(o.clone())},
(&Exclude(ref p), &Include(ref o))
=> if p < o {Exclude(p.clone())} else {Include(o.clone())},
(&Exclude(ref p), &Exclude(ref o))
=> if p < o {Exclude(p.clone())} else {Exclude(o.clone())},
_ => Infinite,
}
}
pub(in crate) fn least_intersect(&self, other: &Self) -> Self {
match (self, other) {
(&Include(ref p), &Include(ref o))
=> if p < o {Include(p.clone())} else {Include(o.clone())},
(&Include(ref p), &Exclude(ref o))
=> if p < o {Include(p.clone())} else {Exclude(o.clone())},
(&Exclude(ref p), &Include(ref o))
=> if p <= o {Exclude(p.clone())} else {Include(o.clone())},
(&Exclude(ref p), &Exclude(ref o))
=> if p < o {Exclude(p.clone())} else {Exclude(o.clone())},
(&Include(ref p), &Infinite) => Include(p.clone()),
(&Exclude(ref p), &Infinite) => Exclude(p.clone()),
(&Infinite, &Include(ref o)) => Include(o.clone()),
(&Infinite, &Exclude(ref o)) => Exclude(o.clone()),
_ => Infinite,
}
}
pub(in crate) fn greatest_union(&self, other: &Self) -> Self {
match (self, other) {
(&Include(ref p), &Include(ref o))
=> if p > o {Include(p.clone())} else {Include(o.clone())},
(&Include(ref p), &Exclude(ref o))
=> if p >= o {Include(p.clone())} else {Exclude(o.clone())},
(&Exclude(ref p), &Include(ref o))
=> if p > o {Exclude(p.clone())} else {Include(o.clone())},
(&Exclude(ref p), &Exclude(ref o))
=> if p > o {Exclude(p.clone())} else {Exclude(o.clone())},
_ => Infinite,
}
}
pub(in crate) fn greatest_intersect(&self, other: &Self) -> Self {
match (self, other) {
(&Include(ref p), &Include(ref o))
=> if p > o {Include(p.clone())} else {Include(o.clone())},
(&Include(ref p), &Exclude(ref o))
=> if p > o {Include(p.clone())} else {Exclude(o.clone())},
(&Exclude(ref p), &Include(ref o))
=> if p >= o {Exclude(p.clone())} else {Include(o.clone())},
(&Exclude(ref p), &Exclude(ref o))
=> if p > o {Exclude(p.clone())} else {Exclude(o.clone())},
(&Include(ref p), &Infinite) => Include(p.clone()),
(&Exclude(ref p), &Infinite) => Exclude(p.clone()),
(&Infinite, &Include(ref o)) => Include(o.clone()),
(&Infinite, &Exclude(ref o)) => Exclude(o.clone()),
_ => Infinite,
}
}
pub(in crate) fn union_adjacent(&self, other: &Self) -> bool {
match (self, other) {
(&Include(ref p), &Include(ref o)) |
(&Include(ref p), &Exclude(ref o)) |
(&Exclude(ref p), &Include(ref o)) if p == o => true,
_ => false,
}
}
}
impl<T> Default for Bound<T> where T: Default {
#[inline]
fn default() -> Self {
Include(Default::default())
}
}
impl<T> From<T> for Bound<T> {
#[inline]
fn from(t: T) -> Self {
Include(t)
}
}