pub mod fat;
#[macro_use]
mod macros;
mod bitset;
mod deferred;
mod duration;
mod hash;
mod pico;
mod round;
mod scalar;
pub use self::bitset::{BitSet, SmallBitSet};
pub use self::deferred::Deferred;
pub use self::duration::format_duration;
pub use self::hash::LazyHash;
pub use self::pico::PicoStr;
pub use self::round::{round_int_with_precision, round_with_precision};
pub use self::scalar::Scalar;
use std::fmt::{Debug, Formatter};
use std::hash::Hash;
use std::iter::{Chain, Flatten, Rev};
use std::num::NonZeroUsize;
use std::ops::{Add, Deref, Div, Mul, Neg, Sub};
use std::sync::Arc;
use siphasher::sip128::{Hasher128, SipHasher13};
#[doc(hidden)]
pub use once_cell;
pub fn debug<F>(f: F) -> impl Debug
where
F: Fn(&mut Formatter) -> std::fmt::Result,
{
struct Wrapper<F>(F);
impl<F> Debug for Wrapper<F>
where
F: Fn(&mut Formatter) -> std::fmt::Result,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.0(f)
}
}
Wrapper(f)
}
pub fn hash128<T: Hash + ?Sized>(value: &T) -> u128 {
let mut state = SipHasher13::new();
value.hash(&mut state);
state.finish128().as_u128()
}
pub trait NonZeroExt {
const ONE: Self;
}
impl NonZeroExt for NonZeroUsize {
const ONE: Self = match Self::new(1) {
Some(v) => v,
None => unreachable!(),
};
}
pub trait ArcExt<T> {
fn take(self) -> T;
}
impl<T: Clone> ArcExt<T> for Arc<T> {
fn take(self) -> T {
match Arc::try_unwrap(self) {
Ok(v) => v,
Err(rc) => (*rc).clone(),
}
}
}
pub trait OptionExt<T> {
fn map_or_default<U: Default, F>(self, f: F) -> U
where
F: FnOnce(T) -> U;
}
impl<T> OptionExt<T> for Option<T> {
fn map_or_default<U: Default, F>(self, f: F) -> U
where
F: FnOnce(T) -> U,
{
match self {
Some(x) => f(x),
None => U::default(),
}
}
}
pub trait SliceExt<T> {
fn trim_start_matches<F>(&self, f: F) -> &[T]
where
F: FnMut(&T) -> bool;
fn trim_end_matches<F>(&self, f: F) -> &[T]
where
F: FnMut(&T) -> bool;
fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F>
where
F: FnMut(&T) -> K,
K: PartialEq;
}
impl<T> SliceExt<T> for [T] {
fn trim_start_matches<F>(&self, mut f: F) -> &[T]
where
F: FnMut(&T) -> bool,
{
let len = self.len();
let mut i = 0;
while i < len && f(&self[i]) {
i += 1;
}
&self[i..]
}
fn trim_end_matches<F>(&self, mut f: F) -> &[T]
where
F: FnMut(&T) -> bool,
{
let mut i = self.len();
while i > 0 && f(&self[i - 1]) {
i -= 1;
}
&self[..i]
}
fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F> {
GroupByKey { slice: self, f }
}
}
pub struct GroupByKey<'a, T, F> {
slice: &'a [T],
f: F,
}
impl<'a, T, K, F> Iterator for GroupByKey<'a, T, F>
where
F: FnMut(&T) -> K,
K: PartialEq,
{
type Item = (K, &'a [T]);
fn next(&mut self) -> Option<Self::Item> {
let mut iter = self.slice.iter();
let key = (self.f)(iter.next()?);
let count = 1 + iter.take_while(|t| (self.f)(t) == key).count();
let (head, tail) = self.slice.split_at(count);
self.slice = tail;
Some((key, head))
}
}
pub trait MaybeReverseIter {
type RevIfIter;
fn rev_if(self, condition: bool) -> Self::RevIfIter
where
Self: Sized;
}
impl<I: Iterator + DoubleEndedIterator> MaybeReverseIter for I {
type RevIfIter =
Chain<Flatten<std::option::IntoIter<I>>, Flatten<std::option::IntoIter<Rev<I>>>>;
fn rev_if(self, condition: bool) -> Self::RevIfIter
where
Self: Sized,
{
let (maybe_self_iter, maybe_rev_iter) =
if condition { (None, Some(self.rev())) } else { (Some(self), None) };
maybe_self_iter
.into_iter()
.flatten()
.chain(maybe_rev_iter.into_iter().flatten())
}
}
pub fn option_eq<L, R>(left: Option<L>, other: R) -> bool
where
L: PartialEq<R>,
{
left.is_some_and(|v| v == other)
}
#[derive(Debug)]
pub struct Static<T: 'static>(pub &'static T);
impl<T> Deref for Static<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<T> Copy for Static<T> {}
impl<T> Clone for Static<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Eq for Static<T> {}
impl<T> PartialEq for Static<T> {
fn eq(&self, other: &Self) -> bool {
std::ptr::eq(self.0, other.0)
}
}
impl<T> Hash for Static<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
state.write_usize(self.0 as *const _ as _);
}
}
pub trait Get<Index> {
type Component;
fn get_ref(&self, index: Index) -> &Self::Component;
fn get_mut(&mut self, index: Index) -> &mut Self::Component;
fn get(self, index: Index) -> Self::Component
where
Self: Sized,
Self::Component: Copy,
{
*self.get_ref(index)
}
fn set(&mut self, index: Index, component: Self::Component) {
*self.get_mut(index) = component;
}
}
pub trait Numeric:
Sized
+ Debug
+ Copy
+ PartialEq
+ Neg<Output = Self>
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<f64, Output = Self>
+ Div<f64, Output = Self>
{
fn zero() -> Self;
fn is_zero(self) -> bool {
self == Self::zero()
}
fn is_finite(self) -> bool;
}