use std::marker;
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Limit {
AtMost(usize),
Unbounded,
}
pub trait Bound {
const LIMIT: Limit;
}
pub enum AtMost<const N: usize> {}
impl<const N: usize> Bound for AtMost<N> {
const LIMIT: Limit = Limit::AtMost(N);
}
pub enum Unbounded {}
impl Bound for Unbounded {
const LIMIT: Limit = Limit::Unbounded;
}
pub struct Max<L, R>(marker::PhantomData<fn() -> (L, R)>);
impl<L: Bound, R: Bound> Bound for Max<L, R> {
const LIMIT: Limit = match (L::LIMIT, R::LIMIT) {
(Limit::AtMost(left), Limit::AtMost(right)) => {
Limit::AtMost(if left > right { left } else { right })
}
(Limit::Unbounded, _) | (_, Limit::Unbounded) => Limit::Unbounded,
};
}