#![warn(anonymous_parameters)]
#![warn(bad_style)]
#![warn(bare_trait_objects)]
#![warn(const_err)]
#![warn(dead_code)]
#![warn(elided_lifetimes_in_paths)]
#![warn(improper_ctypes)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(missing_doc_code_examples)]
#![warn(missing_docs)]
#![warn(no_mangle_generic_items)]
#![warn(non_shorthand_field_patterns)]
#![warn(nonstandard_style)]
#![warn(overflowing_literals)]
#![warn(path_statements)]
#![warn(patterns_in_fns_without_body)]
#![warn(private_in_public)]
#![warn(rust_2018_idioms)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unconditional_recursion)]
#![warn(unreachable_pub)]
#![warn(unused)]
#![warn(unused_allocation)]
#![warn(unused_comparisons)]
#![warn(unused_parens)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![warn(variant_size_differences)]
#![warn(while_true)]
#[cfg(feature = "serde")]
use serde::{ Serialize, Deserialize };
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Few<T> {
Zero,
One(T),
Two(T, T),
}
impl<T> Few<T> {
pub fn is_zero(&self) -> bool {
match self {
Few::Zero => true,
_ => false,
}
}
pub fn is_one(&self) -> bool {
match self {
Few::One(_) => true,
_ => false,
}
}
pub fn is_two(&self) -> bool {
match self {
Few::Two(_, _) => true,
_ => false,
}
}
pub fn contains<U>(&self, x: &U) -> bool
where U: PartialEq<T>
{
match self {
Few::Zero => false,
Few::One(v) => x == v,
Few::Two(a, b) => x == a || x == b,
}
}
pub fn map<F, U>(self, mut f: F) -> Few<U>
where F: FnMut(T) -> U,
{
match self {
Few::Zero => Few::Zero,
Few::One(v) => Few::One((f)(v)),
Few::Two(a, b) => Few::Two((f)(a), (f)(b)),
}
}
}
impl<T> Iterator for Few<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
let mut res = None;
replace_with(self, |curr|
match curr {
Few::Zero => { res = None; Few::Zero },
Few::One(v) => { res = Some(v); Few::Zero },
Few::Two(a, b) => { res = Some(a); Few::One(b) },
}
);
res
}
}
impl<T> DoubleEndedIterator for Few<T> {
fn next_back(&mut self) -> Option<T> {
let mut res = None;
replace_with(self, |curr|
match curr {
Few::Zero => { res = None; Few::Zero },
Few::One(v) => { res = Some(v); Few::Zero },
Few::Two(a, b) => { res = Some(b); Few::One(a) },
}
);
res
}
}
impl<T> ExactSizeIterator for Few<T> {
fn len(&self) -> usize {
match self {
Few::Zero => 0,
Few::One(_) => 1,
Few::Two(_, _) => 2,
}
}
}
impl<T> std::iter::FusedIterator for Few<T> {}
impl<T> Default for Few<T> {
fn default() -> Self {
Few::Zero
}
}
impl<T> From<T> for Few<T> {
fn from(value: T) -> Self {
Few::One(value)
}
}
impl<T> From<(T, T)> for Few<T> {
fn from(value: (T, T)) -> Self {
Few::Two(value.0, value.1)
}
}
impl<T> From<Option<T>> for Few<T> {
fn from(value: Option<T>) -> Self {
match value {
None => Few::Zero,
Some(value) => Few::One(value),
}
}
}
impl<T> From<Option<(T, T)>> for Few<T> {
fn from(value: Option<(T, T)>) -> Self {
match value {
None => Few::Zero,
Some((a, b)) => Few::Two(a, b),
}
}
}
impl<T> From<(Option<T>, Option<T>)> for Few<T> {
fn from(value: (Option<T>, Option<T>)) -> Self {
match (value.0, value.1) {
(None, None) => Few::Zero,
(Some(a), None) => Few::One(a),
(None, Some(b)) => Few::One(b),
(Some(a), Some(b)) => Few::Two(a, b),
}
}
}
impl<T> Into<Option<(T, T)>> for Few<T> where T: Clone {
fn into(self) -> Option<(T, T)> {
match self {
Few::Zero => None,
Few::One(v) => Some((v.clone(), v)),
Few::Two(a, b) => Some((a, b)),
}
}
}
#[inline]
fn replace_with<T, F>(val: &mut T, replace: F)
where F: FnOnce(T) -> T {
let guard = ExitGuard;
unsafe {
let old = std::ptr::read(val);
let new = replace(old);
std::ptr::write(val, new);
}
std::mem::forget(guard);
}
struct ExitGuard;
impl Drop for ExitGuard {
fn drop(&mut self) {
panic!("`replace_with` closure unwind");
}
}