use std::cmp::Ordering;
use std::collections::{LinkedList as StdLinkedList, VecDeque};
use std::fmt;
use std::ops::{Add, Div, Index, IndexMut, Mul, Neg, Sub};
#[derive(Debug, Clone)]
pub struct Deque<T> {
inner: VecDeque<T>,
}
impl<T> Deque<T> {
pub fn new() -> Self {
Self {
inner: VecDeque::new(),
}
}
pub fn with_capacity(cap: usize) -> Self {
Self {
inner: VecDeque::with_capacity(cap),
}
}
pub fn size(&self) -> usize {
self.inner.len()
}
pub fn empty(&self) -> bool {
self.inner.is_empty()
}
pub fn clear(&mut self) {
self.inner.clear()
}
pub fn push_back(&mut self, value: T) {
self.inner.push_back(value)
}
pub fn push_front(&mut self, value: T) {
self.inner.push_front(value)
}
pub fn pop_back(&mut self) -> Option<T> {
self.inner.pop_back()
}
pub fn pop_front(&mut self) -> Option<T> {
self.inner.pop_front()
}
pub fn get(&self, i: usize) -> Option<&T> {
self.inner.get(i)
}
pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
self.inner.get_mut(i)
}
pub fn front(&self) -> Option<&T> {
self.inner.front()
}
pub fn back(&self) -> Option<&T> {
self.inner.back()
}
pub fn front_mut(&mut self) -> Option<&mut T> {
self.inner.front_mut()
}
pub fn back_mut(&mut self) -> Option<&mut T> {
self.inner.back_mut()
}
pub fn resize(&mut self, new_len: usize, value: T)
where
T: Clone,
{
self.inner.resize(new_len, value)
}
pub fn shrink_to_fit(&mut self) {
self.inner.shrink_to_fit()
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.inner.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.inner.iter_mut()
}
pub fn insert(&mut self, index: usize, value: T) {
self.inner.insert(index, value)
}
pub fn remove(&mut self, index: usize) -> Option<T> {
self.inner.remove(index)
}
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.inner, &mut other.inner)
}
}
impl<T> Index<usize> for Deque<T> {
type Output = T;
fn index(&self, i: usize) -> &T {
&self.inner[i]
}
}
impl<T> IndexMut<usize> for Deque<T> {
fn index_mut(&mut self, i: usize) -> &mut T {
&mut self.inner[i]
}
}
impl<T> Default for Deque<T> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct List<T> {
inner: StdLinkedList<T>,
}
pub struct ListIter<'a, T> {
inner: std::collections::linked_list::Iter<'a, T>,
}
impl<'a, T> Iterator for ListIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.inner.next()
}
}
impl<T> List<T> {
pub fn new() -> Self {
Self {
inner: StdLinkedList::new(),
}
}
pub fn size(&self) -> usize {
self.inner.len()
}
pub fn empty(&self) -> bool {
self.inner.is_empty()
}
pub fn push_back(&mut self, value: T) {
self.inner.push_back(value)
}
pub fn push_front(&mut self, value: T) {
self.inner.push_front(value)
}
pub fn pop_back(&mut self) -> Option<T> {
self.inner.pop_back()
}
pub fn pop_front(&mut self) -> Option<T> {
self.inner.pop_front()
}
pub fn front(&self) -> Option<&T> {
self.inner.front()
}
pub fn back(&self) -> Option<&T> {
self.inner.back()
}
pub fn front_mut(&mut self) -> Option<&mut T> {
self.inner.front_mut()
}
pub fn back_mut(&mut self) -> Option<&mut T> {
self.inner.back_mut()
}
pub fn clear(&mut self) {
self.inner.clear()
}
pub fn iter(&self) -> ListIter<T> {
ListIter {
inner: self.inner.iter(),
}
}
pub fn insert(&mut self, index: usize, value: T) {
let mut split = self.inner.split_off(index);
self.inner.push_back(value);
self.inner.append(&mut split);
}
pub fn erase(&mut self, index: usize) -> Option<T> {
if index >= self.inner.len() {
return None;
}
let mut split = self.inner.split_off(index);
let result = split.pop_front();
self.inner.append(&mut split);
result
}
pub fn splice(&mut self, pos: usize, other: &mut Self) {
let mut split = self.inner.split_off(pos);
self.inner.append(&mut other.inner);
self.inner.append(&mut split);
}
pub fn merge(&mut self, other: &mut Self)
where
T: Ord,
{
let mut result = StdLinkedList::new();
loop {
match (self.inner.front(), other.inner.front()) {
(Some(a), Some(b)) if a <= b => {
result.push_back(self.inner.pop_front().unwrap());
}
(Some(_), Some(_)) => {
result.push_back(other.inner.pop_front().unwrap());
}
(Some(_), None) => {
result.append(&mut self.inner);
break;
}
(None, _) => {
result.append(&mut other.inner);
break;
}
}
}
self.inner = result;
}
pub fn merge_by<F>(&mut self, other: &mut Self, mut cmp: F)
where
F: FnMut(&T, &T) -> Ordering,
{
let mut result = StdLinkedList::new();
loop {
match (self.inner.front(), other.inner.front()) {
(Some(a), Some(b)) if cmp(a, b) != Ordering::Greater => {
result.push_back(self.inner.pop_front().unwrap());
}
(Some(_), Some(_)) => {
result.push_back(other.inner.pop_front().unwrap());
}
(Some(_), None) => {
result.append(&mut self.inner);
break;
}
(None, _) => {
result.append(&mut other.inner);
break;
}
}
}
self.inner = result;
}
pub fn sort(&mut self)
where
T: Ord,
{
let mut v: Vec<T> = std::mem::take(&mut self.inner).into_iter().collect();
v.sort();
self.inner = v.into_iter().collect();
}
pub fn sort_by<F>(&mut self, cmp: F)
where
F: FnMut(&T, &T) -> Ordering,
{
let mut v: Vec<T> = std::mem::take(&mut self.inner).into_iter().collect();
v.sort_by(cmp);
self.inner = v.into_iter().collect();
}
pub fn reverse(&mut self) {
let mut v: Vec<T> = std::mem::take(&mut self.inner).into_iter().collect();
v.reverse();
self.inner = v.into_iter().collect();
}
pub fn unique(&mut self)
where
T: PartialEq,
{
let mut v: Vec<T> = std::mem::take(&mut self.inner).into_iter().collect();
v.dedup();
self.inner = v.into_iter().collect();
}
pub fn unique_by<F>(&mut self, mut pred: F)
where
F: FnMut(&T, &T) -> bool,
{
let mut v: Vec<T> = std::mem::take(&mut self.inner).into_iter().collect();
v.dedup_by(|a, b| pred(a, b));
self.inner = v.into_iter().collect();
}
pub fn remove(&mut self, value: &T) -> usize
where
T: PartialEq,
{
let old_len = self.inner.len();
let v: Vec<T> = std::mem::take(&mut self.inner)
.into_iter()
.filter(|x| x != value)
.collect();
let removed = old_len - v.len();
self.inner = v.into_iter().collect();
removed
}
pub fn remove_if<F>(&mut self, pred: F) -> usize
where
F: Fn(&T) -> bool,
{
let old_len = self.inner.len();
let v: Vec<T> = std::mem::take(&mut self.inner)
.into_iter()
.filter(|x| !pred(x))
.collect();
let removed = old_len - v.len();
self.inner = v.into_iter().collect();
removed
}
pub fn resize(&mut self, new_len: usize, value: T)
where
T: Clone,
{
let cur = self.inner.len();
if new_len > cur {
for _ in 0..(new_len - cur) {
self.inner.push_back(value.clone());
}
} else {
for _ in 0..(cur - new_len) {
self.inner.pop_back();
}
}
}
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.inner, &mut other.inner)
}
}
impl<T> Default for List<T> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct ForwardList<T> {
inner: Vec<T>,
}
impl<T> ForwardList<T> {
pub fn new() -> Self {
Self { inner: Vec::new() }
}
pub fn size(&self) -> usize {
self.inner.len()
}
pub fn empty(&self) -> bool {
self.inner.is_empty()
}
pub fn push_front(&mut self, value: T) {
self.inner.insert(0, value)
}
pub fn pop_front(&mut self) -> Option<T> {
if self.inner.is_empty() {
None
} else {
Some(self.inner.remove(0))
}
}
pub fn front(&self) -> Option<&T> {
self.inner.first()
}
pub fn front_mut(&mut self) -> Option<&mut T> {
self.inner.first_mut()
}
pub fn insert_after(&mut self, index: usize, value: T) {
if index < self.inner.len() {
self.inner.insert(index + 1, value)
} else {
self.inner.push(value)
}
}
pub fn erase_after(&mut self, index: usize) -> Option<T> {
if index + 1 < self.inner.len() {
Some(self.inner.remove(index + 1))
} else {
None
}
}
pub fn splice_after(&mut self, pos: usize, other: &mut Self) {
let other_elems: Vec<T> = std::mem::take(&mut other.inner);
let mut i = pos + 1;
for elem in other_elems {
if i <= self.inner.len() {
self.inner.insert(i, elem);
} else {
self.inner.push(elem);
}
i += 1;
}
}
pub fn reverse(&mut self) {
self.inner.reverse()
}
pub fn sort(&mut self)
where
T: Ord,
{
self.inner.sort()
}
pub fn sort_by<F>(&mut self, cmp: F)
where
F: FnMut(&T, &T) -> Ordering,
{
self.inner.sort_by(cmp)
}
pub fn remove(&mut self, value: &T) -> usize
where
T: PartialEq,
{
let old_len = self.inner.len();
self.inner.retain(|x| x != value);
old_len - self.inner.len()
}
pub fn remove_if<F>(&mut self, pred: F) -> usize
where
F: Fn(&T) -> bool,
{
let old_len = self.inner.len();
self.inner.retain(|x| !pred(x));
old_len - self.inner.len()
}
pub fn unique(&mut self)
where
T: PartialEq,
{
self.inner.dedup()
}
pub fn merge(&mut self, other: &mut Self)
where
T: Ord,
{
let mut other_inner = std::mem::take(&mut other.inner);
self.inner.append(&mut other_inner);
self.inner.sort();
}
pub fn clear(&mut self) {
self.inner.clear()
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.inner.iter()
}
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.inner, &mut other.inner)
}
}
impl<T> Default for ForwardList<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Index<usize> for ForwardList<T> {
type Output = T;
fn index(&self, i: usize) -> &T {
&self.inner[i]
}
}
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct UnorderedMap<K, V>
where
K: std::hash::Hash + Eq,
{
inner: HashMap<K, V>,
}
impl<K, V> UnorderedMap<K, V>
where
K: std::hash::Hash + Eq,
{
pub fn new() -> Self {
Self {
inner: HashMap::new(),
}
}
pub fn with_capacity(cap: usize) -> Self {
Self {
inner: HashMap::with_capacity(cap),
}
}
pub fn size(&self) -> usize {
self.inner.len()
}
pub fn empty(&self) -> bool {
self.inner.is_empty()
}
pub fn get_or_default(&mut self, key: K, default: V) -> &mut V {
self.inner.entry(key).or_insert(default)
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.inner.insert(key, value)
}
pub fn find(&self, key: &K) -> Option<&V> {
self.inner.get(key)
}
pub fn find_mut(&mut self, key: &K) -> Option<&mut V> {
self.inner.get_mut(key)
}
pub fn erase(&mut self, key: &K) -> Option<V> {
self.inner.remove(key)
}
pub fn contains(&self, key: &K) -> bool {
self.inner.contains_key(key)
}
pub fn bucket_count(&self) -> usize {
self.inner.capacity()
}
pub fn load_factor(&self) -> f64 {
if self.inner.capacity() == 0 {
0.0
} else {
self.inner.len() as f64 / self.inner.capacity() as f64
}
}
pub fn max_load_factor(&self) -> f64 {
1.0
}
pub fn rehash(&mut self, count: usize) {
self.inner.reserve(count.saturating_sub(self.inner.len()));
}
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
}
pub fn clear(&mut self) {
self.inner.clear()
}
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
self.inner.iter()
}
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.inner.keys()
}
pub fn values(&self) -> impl Iterator<Item = &V> {
self.inner.values()
}
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
self.inner.values_mut()
}
pub fn max_bucket_count(&self) -> usize {
usize::MAX
}
pub fn bucket(&self, _key: &K) -> usize {
0
}
pub fn bucket_size(&self, _n: usize) -> usize {
self.inner.len()
}
}
impl<K, V> Index<&K> for UnorderedMap<K, V>
where
K: std::hash::Hash + Eq,
{
type Output = V;
fn index(&self, key: &K) -> &V {
self.inner.get(key).expect("key not found in UnorderedMap")
}
}
impl<K, V> Default for UnorderedMap<K, V>
where
K: std::hash::Hash + Eq,
{
fn default() -> Self {
Self::new()
}
}
use std::collections::HashSet;
#[derive(Debug, Clone)]
pub struct UnorderedSet<T>
where
T: std::hash::Hash + Eq,
{
inner: HashSet<T>,
}
impl<T> UnorderedSet<T>
where
T: std::hash::Hash + Eq,
{
pub fn new() -> Self {
Self {
inner: HashSet::new(),
}
}
pub fn with_capacity(cap: usize) -> Self {
Self {
inner: HashSet::with_capacity(cap),
}
}
pub fn size(&self) -> usize {
self.inner.len()
}
pub fn empty(&self) -> bool {
self.inner.is_empty()
}
pub fn insert(&mut self, value: T) -> bool {
self.inner.insert(value)
}
pub fn find(&self, value: &T) -> Option<&T> {
self.inner.get(value)
}
pub fn erase(&mut self, value: &T) -> bool {
self.inner.remove(value)
}
pub fn contains(&self, value: &T) -> bool {
self.inner.contains(value)
}
pub fn bucket_count(&self) -> usize {
self.inner.capacity()
}
pub fn load_factor(&self) -> f64 {
if self.inner.capacity() == 0 {
0.0
} else {
self.inner.len() as f64 / self.inner.capacity() as f64
}
}
pub fn rehash(&mut self, count: usize) {
self.inner.reserve(count.saturating_sub(self.inner.len()));
}
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
}
pub fn clear(&mut self) {
self.inner.clear()
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.inner.iter()
}
pub fn max_bucket_count(&self) -> usize {
usize::MAX
}
pub fn bucket(&self, _value: &T) -> usize {
0
}
pub fn bucket_size(&self, _n: usize) -> usize {
self.inner.len()
}
}
impl<T> Default for UnorderedSet<T>
where
T: std::hash::Hash + Eq,
{
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StdArray<T, const N: usize> {
data: [T; N],
}
impl<T: Default + Copy, const N: usize> StdArray<T, N> {
pub fn new() -> Self {
Self {
data: [T::default(); N],
}
}
}
impl<T, const N: usize> StdArray<T, N> {
pub fn from_array(arr: [T; N]) -> Self {
Self { data: arr }
}
pub fn size(&self) -> usize {
N
}
pub fn empty(&self) -> bool {
N == 0
}
pub fn max_size(&self) -> usize {
N
}
pub fn front(&self) -> &T {
&self.data[0]
}
pub fn back(&self) -> &T {
&self.data[N - 1]
}
pub fn front_mut(&mut self) -> &mut T {
&mut self.data[0]
}
pub fn back_mut(&mut self) -> &mut T {
&mut self.data[N - 1]
}
pub fn data(&self) -> *const T {
self.data.as_ptr()
}
pub fn data_mut(&mut self) -> *mut T {
self.data.as_mut_ptr()
}
pub fn as_slice(&self) -> &[T] {
&self.data
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.data
}
pub fn fill(&mut self, value: T)
where
T: Clone,
{
for item in self.data.iter_mut() {
*item = value.clone();
}
}
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.data, &mut other.data)
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.data.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.data.iter_mut()
}
pub fn begin(&self) -> *const T {
self.data.as_ptr()
}
pub fn end(&self) -> *const T {
unsafe { self.data.as_ptr().add(N) }
}
}
impl<T, const N: usize> Index<usize> for StdArray<T, N> {
type Output = T;
fn index(&self, i: usize) -> &T {
&self.data[i]
}
}
impl<T, const N: usize> IndexMut<usize> for StdArray<T, N> {
fn index_mut(&mut self, i: usize) -> &mut T {
&mut self.data[i]
}
}
impl<T: Default + Copy, const N: usize> Default for StdArray<T, N> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct Stack<T> {
inner: Vec<T>,
}
impl<T> Stack<T> {
pub fn new() -> Self {
Self { inner: Vec::new() }
}
pub fn push(&mut self, value: T) {
self.inner.push(value)
}
pub fn pop(&mut self) -> Option<T> {
self.inner.pop()
}
pub fn top(&self) -> Option<&T> {
self.inner.last()
}
pub fn top_mut(&mut self) -> Option<&mut T> {
self.inner.last_mut()
}
pub fn size(&self) -> usize {
self.inner.len()
}
pub fn empty(&self) -> bool {
self.inner.is_empty()
}
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.inner, &mut other.inner)
}
}
impl<T> Default for Stack<T> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct Queue<T> {
inner: VecDeque<T>,
}
impl<T> Queue<T> {
pub fn new() -> Self {
Self {
inner: VecDeque::new(),
}
}
pub fn push(&mut self, value: T) {
self.inner.push_back(value)
}
pub fn pop(&mut self) -> Option<T> {
self.inner.pop_front()
}
pub fn front(&self) -> Option<&T> {
self.inner.front()
}
pub fn back(&self) -> Option<&T> {
self.inner.back()
}
pub fn front_mut(&mut self) -> Option<&mut T> {
self.inner.front_mut()
}
pub fn back_mut(&mut self) -> Option<&mut T> {
self.inner.back_mut()
}
pub fn size(&self) -> usize {
self.inner.len()
}
pub fn empty(&self) -> bool {
self.inner.is_empty()
}
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.inner, &mut other.inner)
}
}
impl<T> Default for Queue<T> {
fn default() -> Self {
Self::new()
}
}
use std::collections::BinaryHeap;
#[derive(Debug, Clone)]
pub struct PriorityQueue<T: Ord> {
inner: BinaryHeap<T>,
}
impl<T: Ord> PriorityQueue<T> {
pub fn new() -> Self {
Self {
inner: BinaryHeap::new(),
}
}
pub fn with_capacity(cap: usize) -> Self {
Self {
inner: BinaryHeap::with_capacity(cap),
}
}
pub fn push(&mut self, value: T) {
self.inner.push(value)
}
pub fn pop(&mut self) -> Option<T> {
self.inner.pop()
}
pub fn top(&self) -> Option<&T> {
self.inner.peek()
}
pub fn size(&self) -> usize {
self.inner.len()
}
pub fn empty(&self) -> bool {
self.inner.is_empty()
}
pub fn clear(&mut self) {
self.inner.clear()
}
pub fn from_vec(vec: Vec<T>) -> Self {
Self {
inner: BinaryHeap::from(vec),
}
}
pub fn into_sorted_vec(self) -> Vec<T> {
self.inner.into_sorted_vec()
}
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.inner, &mut other.inner)
}
}
impl<T: Ord> Default for PriorityQueue<T> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Bitset<const N: usize> {
blocks: Vec<u64>,
}
impl<const N: usize> Bitset<N> {
fn block_count() -> usize {
(N + 63) / 64
}
pub fn new() -> Self {
Self {
blocks: vec![0u64; Self::block_count()],
}
}
pub fn set_all(&mut self) {
for b in self.blocks.iter_mut() {
*b = u64::MAX;
}
self.clear_excess_bits();
}
pub fn set(&mut self, pos: usize, value: bool) {
if pos >= N {
return;
}
let (block, bit) = (pos / 64, pos % 64);
if value {
self.blocks[block] |= 1u64 << bit;
} else {
self.blocks[block] &= !(1u64 << bit);
}
}
pub fn reset_all(&mut self) {
for b in self.blocks.iter_mut() {
*b = 0;
}
}
pub fn reset(&mut self, pos: usize) {
self.set(pos, false)
}
pub fn flip_all(&mut self) {
for b in self.blocks.iter_mut() {
*b = !*b;
}
self.clear_excess_bits();
}
pub fn flip(&mut self, pos: usize) {
if pos >= N {
return;
}
let (block, bit) = (pos / 64, pos % 64);
self.blocks[block] ^= 1u64 << bit;
}
pub fn test(&self, pos: usize) -> bool {
if pos >= N {
return false;
}
let (block, bit) = (pos / 64, pos % 64);
(self.blocks[block] >> bit) & 1 == 1
}
pub fn size(&self) -> usize {
N
}
pub fn count(&self) -> usize {
self.blocks.iter().map(|b| b.count_ones() as usize).sum()
}
pub fn all(&self) -> bool {
if N == 0 {
return true;
}
let bc = Self::block_count();
let mask = self.full_mask();
for (i, b) in self.blocks.iter().enumerate() {
let expected = if i == bc - 1 && N % 64 != 0 {
mask
} else {
u64::MAX
};
if *b != expected {
return false;
}
}
true
}
pub fn any(&self) -> bool {
self.blocks.iter().any(|b| *b != 0)
}
pub fn none(&self) -> bool {
self.blocks.iter().all(|b| *b == 0)
}
pub fn to_string(&self) -> String {
if N == 0 {
return String::new();
}
let mut s = String::with_capacity(N);
for i in (0..N).rev() {
s.push(if self.test(i) { '1' } else { '0' });
}
s
}
pub fn to_ulong(&self) -> Option<u64> {
if N > 64 {
return None;
}
Some(self.blocks[0] & self.full_mask())
}
pub fn to_ullong(&self) -> Option<u64> {
self.to_ulong()
}
pub fn and(&self, other: &Self) -> Self {
let mut result = self.clone();
for (i, b) in result.blocks.iter_mut().enumerate() {
*b &= other.blocks[i];
}
result
}
pub fn or(&self, other: &Self) -> Self {
let mut result = self.clone();
for (i, b) in result.blocks.iter_mut().enumerate() {
*b |= other.blocks[i];
}
result
}
pub fn xor(&self, other: &Self) -> Self {
let mut result = self.clone();
for (i, b) in result.blocks.iter_mut().enumerate() {
*b ^= other.blocks[i];
}
result
}
pub fn not(&self) -> Self {
let mut result = self.clone();
result.flip_all();
result
}
pub fn shift_left(&self, n: usize) -> Self {
let mut result = Bitset::new();
for i in 0..N {
if i >= n && self.test(i - n) {
result.set(i, true);
}
}
result
}
pub fn shift_right(&self, n: usize) -> Self {
let mut result = Bitset::new();
for i in 0..N {
if i + n < N && self.test(i + n) {
result.set(i, true);
}
}
result
}
fn full_mask(&self) -> u64 {
if N == 0 {
return 0;
}
if N % 64 == 0 {
u64::MAX
} else {
(1u64 << (N % 64)) - 1
}
}
fn clear_excess_bits(&mut self) {
if N % 64 != 0 {
let last = Self::block_count() - 1;
self.blocks[last] &= self.full_mask();
}
}
}
impl<const N: usize> Default for Bitset<N> {
fn default() -> Self {
Self::new()
}
}
impl<const N: usize> fmt::Display for Bitset<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.to_string())
}
}
#[derive(Debug, Clone)]
pub struct ValArray<T> {
data: Vec<T>,
}
impl<T> ValArray<T> {
pub fn new() -> Self {
Self { data: Vec::new() }
}
pub fn from_elem(n: usize, value: T) -> Self
where
T: Clone,
{
Self {
data: vec![value; n],
}
}
pub fn size(&self) -> usize {
self.data.len()
}
pub fn as_slice(&self) -> &[T] {
&self.data
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.data.iter()
}
pub fn apply<F>(&self, f: F) -> Self
where
F: Fn(&T) -> T,
{
Self {
data: self.data.iter().map(f).collect(),
}
}
pub fn sum(&self) -> T
where
T: std::iter::Sum<T> + Copy,
{
self.data.iter().copied().sum()
}
pub fn min(&self) -> Option<&T>
where
T: PartialOrd,
{
self.data.iter().min_by(|a, b| a.partial_cmp(b).unwrap())
}
pub fn max(&self) -> Option<&T>
where
T: PartialOrd,
{
self.data.iter().max_by(|a, b| a.partial_cmp(b).unwrap())
}
pub fn cshift(&self, n: isize) -> Self
where
T: Clone,
{
let len = self.data.len();
if len == 0 {
return Self::new();
}
let shift = ((n % len as isize) + len as isize) as usize % len;
let mut result = Vec::with_capacity(len);
result.extend_from_slice(&self.data[shift..]);
result.extend_from_slice(&self.data[..shift]);
Self { data: result }
}
pub fn shift(&self, n: isize) -> Self
where
T: Default + Clone,
{
let len = self.data.len();
let mut result = vec![T::default(); len];
if n >= 0 {
let n = n as usize;
for i in 0..len.saturating_sub(n) {
result[i] = self.data[i + n].clone();
}
} else {
let n = (-n) as usize;
for i in n..len {
result[i] = self.data[i - n].clone();
}
}
Self { data: result }
}
pub fn resize(&mut self, new_len: usize, value: T)
where
T: Clone,
{
self.data.resize(new_len, value)
}
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.data, &mut other.data)
}
}
impl<T> Index<usize> for ValArray<T> {
type Output = T;
fn index(&self, i: usize) -> &T {
&self.data[i]
}
}
impl<T> IndexMut<usize> for ValArray<T> {
fn index_mut(&mut self, i: usize) -> &mut T {
&mut self.data[i]
}
}
impl<T: Default> Default for ValArray<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Add<Output = T> + Clone> Add for &ValArray<T> {
type Output = ValArray<T>;
fn add(self, rhs: Self) -> ValArray<T> {
let len = self.data.len().min(rhs.data.len());
ValArray {
data: self.data[..len]
.iter()
.zip(rhs.data[..len].iter())
.map(|(a, b)| a.clone() + b.clone())
.collect(),
}
}
}
impl<T: Sub<Output = T> + Clone> Sub for &ValArray<T> {
type Output = ValArray<T>;
fn sub(self, rhs: Self) -> ValArray<T> {
let len = self.data.len().min(rhs.data.len());
ValArray {
data: self.data[..len]
.iter()
.zip(rhs.data[..len].iter())
.map(|(a, b)| a.clone() - b.clone())
.collect(),
}
}
}
impl<T: Mul<Output = T> + Clone> Mul for &ValArray<T> {
type Output = ValArray<T>;
fn mul(self, rhs: Self) -> ValArray<T> {
let len = self.data.len().min(rhs.data.len());
ValArray {
data: self.data[..len]
.iter()
.zip(rhs.data[..len].iter())
.map(|(a, b)| a.clone() * b.clone())
.collect(),
}
}
}
impl<T: Div<Output = T> + Clone> Div for &ValArray<T> {
type Output = ValArray<T>;
fn div(self, rhs: Self) -> ValArray<T> {
let len = self.data.len().min(rhs.data.len());
ValArray {
data: self.data[..len]
.iter()
.zip(rhs.data[..len].iter())
.map(|(a, b)| a.clone() / b.clone())
.collect(),
}
}
}
impl<T: Neg<Output = T> + Clone> Neg for &ValArray<T> {
type Output = ValArray<T>;
fn neg(self) -> ValArray<T> {
ValArray {
data: self.data.iter().map(|x| -x.clone()).collect(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Complex<T> {
pub re: T,
pub im: T,
}
impl<T: Default> Complex<T> {
pub fn new(re: T, im: T) -> Self {
Self { re, im }
}
}
impl<T: Default> Complex<T> {
pub fn real(&self) -> &T {
&self.re
}
pub fn imag(&self) -> &T {
&self.im
}
pub fn set_real(&mut self, re: T) {
self.re = re;
}
pub fn set_imag(&mut self, im: T) {
self.im = im;
}
}
impl Complex<f64> {
pub fn abs(&self) -> f64 {
(self.re * self.re + self.im * self.im).sqrt()
}
pub fn arg(&self) -> f64 {
self.im.atan2(self.re)
}
pub fn norm(&self) -> f64 {
self.re * self.re + self.im * self.im
}
pub fn conj(&self) -> Self {
Self {
re: self.re,
im: -self.im,
}
}
pub fn polar(r: f64, theta: f64) -> Self {
Self {
re: r * theta.cos(),
im: r * theta.sin(),
}
}
pub fn exp(&self) -> Self {
let e = self.re.exp();
Self {
re: e * self.im.cos(),
im: e * self.im.sin(),
}
}
pub fn ln(&self) -> Self {
Self {
re: self.abs().ln(),
im: self.arg(),
}
}
pub fn log10(&self) -> Self {
let ln10 = 10.0f64.ln();
Self {
re: self.abs().ln() / ln10,
im: self.arg() / ln10,
}
}
pub fn pow(&self, exponent: f64) -> Self {
let r = self.abs().powf(exponent);
let theta = self.arg() * exponent;
Self {
re: r * theta.cos(),
im: r * theta.sin(),
}
}
pub fn sqrt(&self) -> Self {
let r = self.abs();
let re = ((r + self.re) / 2.0).sqrt();
let im = if self.im >= 0.0 {
((r - self.re) / 2.0).sqrt()
} else {
-((r - self.re) / 2.0).sqrt()
};
Self { re, im }
}
pub fn sin(&self) -> Self {
Self {
re: self.re.sin() * self.im.cosh(),
im: self.re.cos() * self.im.sinh(),
}
}
pub fn cos(&self) -> Self {
Self {
re: self.re.cos() * self.im.cosh(),
im: -self.re.sin() * self.im.sinh(),
}
}
pub fn tan(&self) -> Self {
let denom = (2.0 * self.re).cos() + (2.0 * self.im).cosh();
Self {
re: (2.0 * self.re).sin() / denom,
im: (2.0 * self.im).sinh() / denom,
}
}
}
impl<T: Default> Default for Complex<T> {
fn default() -> Self {
Self {
re: T::default(),
im: T::default(),
}
}
}
impl<T: fmt::Display + Default + PartialOrd + std::ops::Neg<Output = T>> fmt::Display for Complex<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({},{})", self.re, self.im)
}
}
impl Add for Complex<f64> {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
re: self.re + rhs.re,
im: self.im + rhs.im,
}
}
}
impl Sub for Complex<f64> {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self {
re: self.re - rhs.re,
im: self.im - rhs.im,
}
}
}
impl Mul for Complex<f64> {
type Output = Self;
fn mul(self, rhs: Self) -> Self {
Self {
re: self.re * rhs.re - self.im * rhs.im,
im: self.re * rhs.im + self.im * rhs.re,
}
}
}
impl Div for Complex<f64> {
type Output = Self;
fn div(self, rhs: Self) -> Self {
let denom = rhs.re * rhs.re + rhs.im * rhs.im;
Self {
re: (self.re * rhs.re + self.im * rhs.im) / denom,
im: (self.im * rhs.re - self.re * rhs.im) / denom,
}
}
}
pub struct RandomDevice;
impl RandomDevice {
pub fn new() -> Self {
Self
}
pub fn next_u32(&self) -> u32 {
let t = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default();
(t.as_nanos() as u32).wrapping_mul(1103515245).wrapping_add(12345)
}
pub fn min(&self) -> u32 {
0
}
pub fn max(&self) -> u32 {
u32::MAX
}
pub fn entropy(&self) -> f64 {
0.0
}
}
impl Default for RandomDevice {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct Mt19937 {
state: [u32; 624],
index: usize,
}
impl Mt19937 {
const N: usize = 624;
const M: usize = 397;
const MATRIX_A: u32 = 0x9908b0df;
const UPPER_MASK: u32 = 0x80000000;
const LOWER_MASK: u32 = 0x7fffffff;
pub fn new(seed: u32) -> Self {
let mut mt = Self {
state: [0u32; Self::N],
index: Self::N,
};
mt.seed(seed);
mt
}
fn seed(&mut self, seed: u32) {
self.state[0] = seed;
for i in 1..Self::N {
self.state[i] = (1812433253u32)
.wrapping_mul(self.state[i - 1] ^ (self.state[i - 1] >> 30))
.wrapping_add(i as u32);
}
self.index = Self::N;
}
fn twist(&mut self) {
for i in 0..Self::N {
let x = (self.state[i] & Self::UPPER_MASK)
| (self.state[(i + 1) % Self::N] & Self::LOWER_MASK);
let mut xa = x >> 1;
if x & 1 == 1 {
xa ^= Self::MATRIX_A;
}
self.state[i] = self.state[(i + Self::M) % Self::N] ^ xa;
}
self.index = 0;
}
pub fn next_u32(&mut self) -> u32 {
if self.index >= Self::N {
self.twist();
}
let mut y = self.state[self.index];
self.index += 1;
y ^= y >> 11;
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= y >> 18;
y
}
pub fn min(&self) -> u32 {
0
}
pub fn max(&self) -> u32 {
u32::MAX
}
}
#[derive(Debug, Clone)]
pub struct UniformIntDistribution {
a: i64,
b: i64,
}
impl UniformIntDistribution {
pub fn new(a: i64, b: i64) -> Self {
Self { a, b }
}
pub fn a(&self) -> i64 {
self.a
}
pub fn b(&self) -> i64 {
self.b
}
pub fn sample(&self, gen: &mut Mt19937) -> i64 {
let range = (self.b - self.a + 1) as u64;
if range == 0 {
return self.a;
}
let r = gen.next_u32() as u64;
self.a + (r % range) as i64
}
}
#[derive(Debug, Clone)]
pub struct UniformRealDistribution {
a: f64,
b: f64,
}
impl UniformRealDistribution {
pub fn new(a: f64, b: f64) -> Self {
Self { a, b }
}
pub fn a(&self) -> f64 {
self.a
}
pub fn b(&self) -> f64 {
self.b
}
pub fn sample(&self, gen: &mut Mt19937) -> f64 {
let r = gen.next_u32() as f64 / u32::MAX as f64;
self.a + r * (self.b - self.a)
}
}
#[derive(Debug, Clone)]
pub struct NormalDistribution {
mean: f64,
stddev: f64,
has_cached: bool,
cached: f64,
}
impl NormalDistribution {
pub fn new(mean: f64, stddev: f64) -> Self {
Self {
mean,
stddev,
has_cached: false,
cached: 0.0,
}
}
pub fn mean(&self) -> f64 {
self.mean
}
pub fn stddev(&self) -> f64 {
self.stddev
}
pub fn sample(&mut self, gen: &mut Mt19937) -> f64 {
if self.has_cached {
self.has_cached = false;
return self.cached * self.stddev + self.mean;
}
let u1 = gen.next_u32() as f64 / u32::MAX as f64;
let u2 = gen.next_u32() as f64 / u32::MAX as f64;
let r = (-2.0 * u1.ln()).sqrt();
let theta = 2.0 * std::f64::consts::PI * u2;
let z0 = r * theta.cos();
let z1 = r * theta.sin();
self.cached = z1;
self.has_cached = true;
z0 * self.stddev + self.mean
}
}
#[derive(Debug, Clone)]
pub struct BernoulliDistribution {
p: f64,
}
impl BernoulliDistribution {
pub fn new(p: f64) -> Self {
Self {
p: p.clamp(0.0, 1.0),
}
}
pub fn p(&self) -> f64 {
self.p
}
pub fn sample(&self, gen: &mut Mt19937) -> bool {
let r = gen.next_u32() as f64 / u32::MAX as f64;
r < self.p
}
}
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct ChronoDuration {
nanos: i64,
}
impl ChronoDuration {
pub fn from_nanos(nanos: i64) -> Self {
Self { nanos }
}
pub fn from_micros(micros: i64) -> Self {
Self {
nanos: micros * 1_000,
}
}
pub fn from_millis(millis: i64) -> Self {
Self {
nanos: millis * 1_000_000,
}
}
pub fn from_seconds(secs: i64) -> Self {
Self {
nanos: secs * 1_000_000_000,
}
}
pub fn count(&self) -> i64 {
self.nanos
}
pub fn zero() -> Self {
Self { nanos: 0 }
}
pub fn min() -> Self {
Self { nanos: i64::MIN }
}
pub fn max() -> Self {
Self { nanos: i64::MAX }
}
pub fn to_std(&self) -> Duration {
Duration::from_nanos(self.nanos.max(0) as u64)
}
}
impl Add for ChronoDuration {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
nanos: self.nanos + rhs.nanos,
}
}
}
impl Sub for ChronoDuration {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self {
nanos: self.nanos - rhs.nanos,
}
}
}
pub fn hours(n: i64) -> ChronoDuration {
ChronoDuration::from_seconds(n * 3600)
}
pub fn minutes(n: i64) -> ChronoDuration {
ChronoDuration::from_seconds(n * 60)
}
pub fn seconds(n: i64) -> ChronoDuration {
ChronoDuration::from_seconds(n)
}
pub fn milliseconds(n: i64) -> ChronoDuration {
ChronoDuration::from_millis(n)
}
pub fn microseconds(n: i64) -> ChronoDuration {
ChronoDuration::from_micros(n)
}
pub fn nanoseconds(n: i64) -> ChronoDuration {
ChronoDuration::from_nanos(n)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct TimePoint {
nanos_since_epoch: i64,
}
impl TimePoint {
pub fn from_nanos(nanos: i64) -> Self {
Self {
nanos_since_epoch: nanos,
}
}
pub fn time_since_epoch(&self) -> ChronoDuration {
ChronoDuration::from_nanos(self.nanos_since_epoch)
}
}
impl Add<ChronoDuration> for TimePoint {
type Output = Self;
fn add(self, rhs: ChronoDuration) -> Self {
Self {
nanos_since_epoch: self.nanos_since_epoch + rhs.count(),
}
}
}
impl Sub<ChronoDuration> for TimePoint {
type Output = Self;
fn sub(self, rhs: ChronoDuration) -> Self {
Self {
nanos_since_epoch: self.nanos_since_epoch - rhs.count(),
}
}
}
impl Sub for TimePoint {
type Output = ChronoDuration;
fn sub(self, rhs: Self) -> ChronoDuration {
ChronoDuration::from_nanos(self.nanos_since_epoch - rhs.nanos_since_epoch)
}
}
pub struct SystemClock;
impl SystemClock {
pub fn now() -> TimePoint {
let dur = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default();
TimePoint::from_nanos(dur.as_nanos() as i64)
}
pub fn to_time_t(tp: &TimePoint) -> i64 {
tp.nanos_since_epoch / 1_000_000_000
}
pub fn from_time_t(t: i64) -> TimePoint {
TimePoint::from_nanos(t * 1_000_000_000)
}
}
pub struct SteadyClock;
impl SteadyClock {
pub fn now() -> TimePoint {
let dur = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default();
TimePoint::from_nanos(dur.as_nanos() as i64)
}
}
pub struct HighResolutionClock;
impl HighResolutionClock {
pub fn now() -> TimePoint {
let dur = Instant::now().elapsed();
TimePoint::from_nanos(dur.as_nanos() as i64)
}
}
use std::sync::{Condvar as StdCondvar, Mutex as StdMutex, MutexGuard};
use std::thread::{self, JoinHandle};
pub struct CxxThread {
handle: Option<JoinHandle<()>>,
id: u64,
}
impl CxxThread {
pub fn new<F>(f: F) -> Self
where
F: FnOnce() + Send + 'static,
{
let handle = thread::spawn(f);
let id = 0u64; Self {
handle: Some(handle),
id,
}
}
pub fn get_id(&self) -> u64 {
self.id
}
pub fn joinable(&self) -> bool {
self.handle.is_some()
}
pub fn join(&mut self) {
if let Some(handle) = self.handle.take() {
let _ = handle.join();
}
}
pub fn detach(&mut self) {
self.handle.take();
}
pub fn hardware_concurrency() -> usize {
thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1)
}
pub fn yield_now() {
thread::yield_now();
}
pub fn sleep_for(dur: Duration) {
thread::sleep(dur);
}
pub fn sleep_until(tp: &TimePoint) {
let now = ChronoDuration::from_nanos(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_nanos() as i64,
);
let remaining = tp.time_since_epoch().count() - now.count();
if remaining > 0 {
thread::sleep(Duration::from_nanos(remaining as u64));
}
}
}
#[derive(Debug)]
pub struct CxxMutex<T> {
inner: StdMutex<T>,
}
impl<T> CxxMutex<T> {
pub fn new(value: T) -> Self {
Self {
inner: StdMutex::new(value),
}
}
pub fn lock(&self) -> CxxMutexGuard<T> {
CxxMutexGuard {
guard: self.inner.lock().unwrap(),
}
}
pub fn try_lock(&self) -> Option<CxxMutexGuard<T>> {
self.inner.try_lock().ok().map(|guard| CxxMutexGuard { guard })
}
}
pub struct CxxMutexGuard<'a, T> {
guard: MutexGuard<'a, T>,
}
impl<'a, T> std::ops::Deref for CxxMutexGuard<'a, T> {
type Target = T;
fn deref(&self) -> &T {
&self.guard
}
}
impl<'a, T> std::ops::DerefMut for CxxMutexGuard<'a, T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.guard
}
}
pub struct LockGuard<'a, T> {
_guard: MutexGuard<'a, T>,
}
impl<'a, T> LockGuard<'a, T> {
pub fn new(mutex: &'a CxxMutex<T>) -> Self {
Self {
_guard: mutex.inner.lock().unwrap(),
}
}
}
pub struct UniqueLock<'a, T> {
guard: Option<MutexGuard<'a, T>>,
}
impl<'a, T> UniqueLock<'a, T> {
pub fn new(mutex: &'a CxxMutex<T>) -> Self {
Self {
guard: Some(mutex.inner.lock().unwrap()),
}
}
pub fn unlock(&mut self) {
self.guard.take();
}
pub fn owns_lock(&self) -> bool {
self.guard.is_some()
}
pub fn try_lock(mutex: &'a CxxMutex<T>) -> Option<Self> {
mutex.inner.try_lock().ok().map(|g| Self { guard: Some(g) })
}
}
impl<'a, T> std::ops::Deref for UniqueLock<'a, T> {
type Target = T;
fn deref(&self) -> &T {
self.guard.as_ref().unwrap()
}
}
impl<'a, T> std::ops::DerefMut for UniqueLock<'a, T> {
fn deref_mut(&mut self) -> &mut T {
self.guard.as_mut().unwrap()
}
}
pub struct ConditionVariable {
inner: StdCondvar,
mutex: StdMutex<()>,
}
impl ConditionVariable {
pub fn new() -> Self {
Self {
inner: StdCondvar::new(),
mutex: StdMutex::new(()),
}
}
pub fn notify_one(&self) {
self.inner.notify_one();
}
pub fn notify_all(&self) {
self.inner.notify_all();
}
pub fn wait<'a, T>(&self, lock: &mut UniqueLock<'a, T>) {
let guard = lock.guard.take();
let _ = guard;
let mut wait_guard = self.mutex.lock().unwrap();
let _result = self.inner.wait(wait_guard);
drop(_result);
}
pub fn wait_for<'a, T, F>(&self, lock: &mut UniqueLock<'a, T>, dur: Duration, pred: F) -> bool
where
F: Fn() -> bool,
{
let guard = lock.guard.take();
let _ = guard;
if pred() {
return true;
}
let wait_guard = self.mutex.lock().unwrap();
let result = self
.inner
.wait_timeout(wait_guard, dur)
.unwrap();
drop(result);
pred()
}
}
impl Default for ConditionVariable {
fn default() -> Self {
Self::new()
}
}
use std::sync::atomic::{AtomicBool, AtomicI32, AtomicU32, AtomicU64, Ordering as AtomicOrdering};
#[derive(Debug)]
pub struct Atomic<T> {
inner: T,
}
impl Atomic<i32> {
pub fn new(value: i32) -> Self {
let inner = AtomicI32::new(value);
Self {
inner: inner.load(AtomicOrdering::SeqCst),
}
}
pub fn load(&self) -> i32 {
self.inner
}
pub fn store(&mut self, value: i32) {
self.inner = value;
}
pub fn exchange(&mut self, value: i32) -> i32 {
let old = self.inner;
self.inner = value;
old
}
pub fn compare_exchange_strong(&mut self, expected: &mut i32, desired: i32) -> Result<i32, i32> {
let old = self.inner;
if old == *expected {
self.inner = desired;
Ok(old)
} else {
*expected = old;
Err(old)
}
}
pub fn compare_exchange_weak(&mut self, expected: &mut i32, desired: i32) -> Result<i32, i32> {
self.compare_exchange_strong(expected, desired)
}
pub fn fetch_add(&mut self, value: i32) -> i32 {
let old = self.inner;
self.inner = old.wrapping_add(value);
old
}
pub fn fetch_sub(&mut self, value: i32) -> i32 {
let old = self.inner;
self.inner = old.wrapping_sub(value);
old
}
pub fn fetch_and(&mut self, value: i32) -> i32 {
let old = self.inner;
self.inner = old & value;
old
}
pub fn fetch_or(&mut self, value: i32) -> i32 {
let old = self.inner;
self.inner = old | value;
old
}
pub fn fetch_xor(&mut self, value: i32) -> i32 {
let old = self.inner;
self.inner = old ^ value;
old
}
}
impl Atomic<u32> {
pub fn new_u32(value: u32) -> Self {
Self {
inner: AtomicU32::new(value).load(AtomicOrdering::SeqCst),
}
}
pub fn load(&self) -> u32 {
self.inner
}
pub fn store(&mut self, value: u32) {
self.inner = value;
}
pub fn fetch_add(&mut self, value: u32) -> u32 {
let old = self.inner;
self.inner = old.wrapping_add(value);
old
}
pub fn fetch_sub(&mut self, value: u32) -> u32 {
let old = self.inner;
self.inner = old.wrapping_sub(value);
old
}
}
impl Atomic<u64> {
pub fn new_u64(value: u64) -> Self {
Self {
inner: AtomicU64::new(value).load(AtomicOrdering::SeqCst),
}
}
pub fn load(&self) -> u64 {
self.inner
}
pub fn store(&mut self, value: u64) {
self.inner = value;
}
pub fn fetch_add(&mut self, value: u64) -> u64 {
let old = self.inner;
self.inner = old.wrapping_add(value);
old
}
}
impl Atomic<bool> {
pub fn new_bool(value: bool) -> Self {
let a = AtomicBool::new(value);
Self {
inner: a.load(AtomicOrdering::SeqCst),
}
}
pub fn load(&self) -> bool {
self.inner
}
pub fn store(&mut self, value: bool) {
self.inner = value;
}
pub fn exchange(&mut self, value: bool) -> bool {
let old = self.inner;
self.inner = value;
old
}
}
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FsPath {
inner: PathBuf,
}
impl FsPath {
pub fn new(s: &str) -> Self {
Self {
inner: PathBuf::from(s),
}
}
pub fn to_string(&self) -> String {
self.inner.to_string_lossy().to_string()
}
pub fn empty(&self) -> bool {
self.inner.as_os_str().is_empty()
}
pub fn is_absolute(&self) -> bool {
self.inner.is_absolute()
}
pub fn is_relative(&self) -> bool {
self.inner.is_relative()
}
pub fn filename(&self) -> Option<FsPath> {
self.inner.file_name().map(|s| FsPath {
inner: PathBuf::from(s),
})
}
pub fn extension(&self) -> Option<String> {
self.inner
.extension()
.map(|s| s.to_string_lossy().to_string())
}
pub fn stem(&self) -> Option<String> {
self.inner
.file_stem()
.map(|s| s.to_string_lossy().to_string())
}
pub fn parent_path(&self) -> Option<FsPath> {
self.inner.parent().map(|p| FsPath {
inner: p.to_path_buf(),
})
}
pub fn root_directory(&self) -> Option<FsPath> {
let ancestors = self.inner.ancestors().collect::<Vec<_>>();
if ancestors.len() >= 2 {
let root = ancestors[ancestors.len() - 2];
Some(FsPath {
inner: root.to_path_buf(),
})
} else {
None
}
}
pub fn exists(&self) -> bool {
self.inner.exists()
}
pub fn is_directory(&self) -> bool {
self.inner.is_dir()
}
pub fn is_regular_file(&self) -> bool {
self.inner.is_file()
}
pub fn file_size(&self) -> Option<u64> {
std::fs::metadata(&self.inner).ok().map(|m| m.len())
}
pub fn create_directory(&self) -> std::io::Result<()> {
std::fs::create_dir(&self.inner)
}
pub fn create_directories(&self) -> std::io::Result<()> {
std::fs::create_dir_all(&self.inner)
}
pub fn remove(&self) -> std::io::Result<()> {
if self.inner.is_dir() {
std::fs::remove_dir(&self.inner)
} else {
std::fs::remove_file(&self.inner)
}
}
pub fn remove_all(&self) -> std::io::Result<()> {
if self.inner.is_dir() {
std::fs::remove_dir_all(&self.inner)
} else {
std::fs::remove_file(&self.inner)
}
}
pub fn rename(&self, to: &FsPath) -> std::io::Result<()> {
std::fs::rename(&self.inner, &to.inner)
}
pub fn copy_file(&self, to: &FsPath) -> std::io::Result<()> {
std::fs::copy(&self.inner, &to.inner).map(|_| ())
}
pub fn canonical(&self) -> Option<FsPath> {
self.inner.canonicalize().ok().map(|p| FsPath { inner: p })
}
pub fn current_path() -> Option<FsPath> {
std::env::current_dir()
.ok()
.map(|p| FsPath { inner: p })
}
pub fn temp_directory_path() -> FsPath {
FsPath {
inner: std::env::temp_dir(),
}
}
pub fn append(&mut self, component: &str) {
self.inner.push(component)
}
pub fn replace_extension(&mut self, ext: &str) {
self.inner.set_extension(ext);
}
pub fn read_to_string(&self) -> std::io::Result<String> {
std::fs::read_to_string(&self.inner)
}
pub fn write_string(&self, content: &str) -> std::io::Result<()> {
std::fs::write(&self.inner, content)
}
}
impl fmt::Display for FsPath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.to_string())
}
}
impl std::ops::Div for &FsPath {
type Output = FsPath;
fn div(self, rhs: Self) -> FsPath {
let mut p = self.inner.clone();
p.push(&rhs.inner);
FsPath { inner: p }
}
}
impl std::ops::Div<&str> for &FsPath {
type Output = FsPath;
fn div(self, rhs: &str) -> FsPath {
let mut p = self.inner.clone();
p.push(rhs);
FsPath { inner: p }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deque_new_empty() {
let d: Deque<i32> = Deque::new();
assert!(d.empty());
assert_eq!(d.size(), 0);
}
#[test]
fn test_deque_push_pop_back() {
let mut d = Deque::new();
d.push_back(1);
d.push_back(2);
d.push_back(3);
assert_eq!(d.size(), 3);
assert_eq!(d.pop_back(), Some(3));
assert_eq!(d.pop_back(), Some(2));
assert_eq!(d.pop_back(), Some(1));
assert!(d.empty());
}
#[test]
fn test_deque_push_pop_front() {
let mut d = Deque::new();
d.push_front(1);
d.push_front(2);
d.push_front(3);
assert_eq!(d.pop_front(), Some(3));
assert_eq!(d.pop_front(), Some(2));
assert_eq!(d.pop_front(), Some(1));
}
#[test]
fn test_deque_mixed() {
let mut d = Deque::new();
d.push_back(2);
d.push_front(1);
d.push_back(3);
assert_eq!(d.front(), Some(&1));
assert_eq!(d.back(), Some(&3));
assert_eq!(d.get(0), Some(&1));
assert_eq!(d.get(1), Some(&2));
assert_eq!(d.get(2), Some(&3));
assert_eq!(d.size(), 3);
}
#[test]
fn test_deque_index() {
let mut d = Deque::new();
d.push_back(10);
d.push_back(20);
d.push_back(30);
assert_eq!(d[0], 10);
assert_eq!(d[1], 20);
assert_eq!(d[2], 30);
}
#[test]
fn test_deque_insert_remove() {
let mut d = Deque::new();
d.push_back(1);
d.push_back(3);
d.insert(1, 2);
assert_eq!(d.size(), 3);
assert_eq!(d[1], 2);
assert_eq!(d.remove(1), Some(2));
assert_eq!(d.size(), 2);
}
#[test]
fn test_deque_swap() {
let mut a = Deque::new();
a.push_back(1);
let mut b = Deque::new();
b.push_back(2);
a.swap(&mut b);
assert_eq!(a[0], 2);
assert_eq!(b[0], 1);
}
#[test]
fn test_deque_resize() {
let mut d = Deque::new();
d.resize(3, 99);
assert_eq!(d.size(), 3);
assert_eq!(d[0], 99);
assert_eq!(d[2], 99);
}
#[test]
fn test_list_new_empty() {
let l: List<i32> = List::new();
assert!(l.empty());
assert_eq!(l.size(), 0);
}
#[test]
fn test_list_push_pop_back() {
let mut l = List::new();
l.push_back(1);
l.push_back(2);
l.push_back(3);
assert_eq!(l.size(), 3);
assert_eq!(l.pop_back(), Some(3));
assert_eq!(l.size(), 2);
}
#[test]
fn test_list_push_pop_front() {
let mut l = List::new();
l.push_front(1);
l.push_front(2);
assert_eq!(l.pop_front(), Some(2));
assert_eq!(l.pop_front(), Some(1));
}
#[test]
fn test_list_front_back() {
let mut l = List::new();
l.push_back(10);
l.push_back(20);
assert_eq!(*l.front().unwrap(), 10);
assert_eq!(*l.back().unwrap(), 20);
}
#[test]
fn test_list_insert_erase() {
let mut l = List::new();
l.push_back(1);
l.push_back(3);
l.insert(1, 2);
assert_eq!(l.size(), 3);
let v: Vec<i32> = l.iter().copied().collect();
assert_eq!(v, vec![1, 2, 3]);
assert_eq!(l.erase(1), Some(2));
assert_eq!(l.size(), 2);
}
#[test]
fn test_list_splice() {
let mut l1 = List::new();
l1.push_back(1);
l1.push_back(4);
let mut l2 = List::new();
l2.push_back(2);
l2.push_back(3);
l1.splice(1, &mut l2);
let v: Vec<i32> = l1.iter().copied().collect();
assert_eq!(v, vec![1, 2, 3, 4]);
assert!(l2.empty());
}
#[test]
fn test_list_sort() {
let mut l = List::new();
l.push_back(3);
l.push_back(1);
l.push_back(2);
l.sort();
let v: Vec<i32> = l.iter().copied().collect();
assert_eq!(v, vec![1, 2, 3]);
}
#[test]
fn test_list_reverse() {
let mut l = List::new();
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.reverse();
let v: Vec<i32> = l.iter().copied().collect();
assert_eq!(v, vec![3, 2, 1]);
}
#[test]
fn test_list_unique() {
let mut l = List::new();
l.push_back(1);
l.push_back(1);
l.push_back(2);
l.push_back(2);
l.push_back(3);
l.unique();
let v: Vec<i32> = l.iter().copied().collect();
assert_eq!(v, vec![1, 2, 3]);
}
#[test]
fn test_list_remove() {
let mut l = List::new();
l.push_back(1);
l.push_back(2);
l.push_back(1);
l.push_back(3);
let removed = l.remove(&1);
assert_eq!(removed, 2);
let v: Vec<i32> = l.iter().copied().collect();
assert_eq!(v, vec![2, 3]);
}
#[test]
fn test_list_remove_if() {
let mut l = List::new();
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
let removed = l.remove_if(|x| *x % 2 == 0);
assert_eq!(removed, 2);
let v: Vec<i32> = l.iter().copied().collect();
assert_eq!(v, vec![1, 3]);
}
#[test]
fn test_list_merge() {
let mut l1 = List::new();
l1.push_back(1);
l1.push_back(3);
l1.push_back(5);
let mut l2 = List::new();
l2.push_back(2);
l2.push_back(4);
l2.push_back(6);
l1.merge(&mut l2);
let v: Vec<i32> = l1.iter().copied().collect();
assert_eq!(v, vec![1, 2, 3, 4, 5, 6]);
}
#[test]
fn test_forward_list_new() {
let fl: ForwardList<i32> = ForwardList::new();
assert!(fl.empty());
}
#[test]
fn test_forward_list_push_pop_front() {
let mut fl = ForwardList::new();
fl.push_front(1);
fl.push_front(2);
fl.push_front(3);
assert_eq!(fl.size(), 3);
assert_eq!(fl.pop_front(), Some(3));
assert_eq!(fl.pop_front(), Some(2));
assert_eq!(fl.pop_front(), Some(1));
}
#[test]
fn test_forward_list_insert_after() {
let mut fl = ForwardList::new();
fl.push_front(3);
fl.push_front(1);
fl.insert_after(0, 2);
assert_eq!(fl.size(), 3);
assert_eq!(fl[0], 1);
assert_eq!(fl[1], 2);
assert_eq!(fl[2], 3);
}
#[test]
fn test_forward_list_erase_after() {
let mut fl = ForwardList::new();
fl.push_front(3);
fl.push_front(2);
fl.push_front(1);
assert_eq!(fl.erase_after(0), Some(2));
assert_eq!(fl.size(), 2);
assert_eq!(fl[0], 1);
assert_eq!(fl[1], 3);
}
#[test]
fn test_forward_list_splice_after() {
let mut fl1 = ForwardList::new();
fl1.push_front(4);
fl1.push_front(1);
let mut fl2 = ForwardList::new();
fl2.push_front(3);
fl2.push_front(2);
fl1.splice_after(0, &mut fl2);
assert_eq!(fl1.size(), 4);
assert_eq!(fl1[0], 1);
assert_eq!(fl1[1], 2);
assert_eq!(fl1[2], 3);
assert_eq!(fl1[3], 4);
}
#[test]
fn test_forward_list_remove_if() {
let mut fl = ForwardList::new();
fl.push_front(4);
fl.push_front(3);
fl.push_front(2);
fl.push_front(1);
fl.remove_if(|x| *x % 2 == 0);
assert_eq!(fl.size(), 2);
assert_eq!(fl[0], 1);
assert_eq!(fl[1], 3);
}
#[test]
fn test_forward_list_sort_reverse() {
let mut fl = ForwardList::new();
fl.push_front(2);
fl.push_front(3);
fl.push_front(1);
fl.sort();
assert_eq!(fl[0], 1);
assert_eq!(fl[1], 2);
assert_eq!(fl[2], 3);
fl.reverse();
assert_eq!(fl[0], 3);
assert_eq!(fl[1], 2);
assert_eq!(fl[2], 1);
}
#[test]
fn test_unordered_map_new() {
let m: UnorderedMap<i32, i32> = UnorderedMap::new();
assert!(m.empty());
assert_eq!(m.size(), 0);
}
#[test]
fn test_unordered_map_insert_find() {
let mut m = UnorderedMap::new();
m.insert(1, 100);
m.insert(2, 200);
assert_eq!(m.size(), 2);
assert_eq!(*m.find(&1).unwrap(), 100);
assert_eq!(*m.find(&2).unwrap(), 200);
assert!(m.find(&3).is_none());
}
#[test]
fn test_unordered_map_insert_overwrite() {
let mut m = UnorderedMap::new();
assert!(m.insert(1, 100).is_none());
assert_eq!(m.insert(1, 200), Some(100));
assert_eq!(*m.find(&1).unwrap(), 200);
}
#[test]
fn test_unordered_map_erase() {
let mut m = UnorderedMap::new();
m.insert(1, 10);
m.insert(2, 20);
assert_eq!(m.erase(&1), Some(10));
assert_eq!(m.size(), 1);
assert!(!m.contains(&1));
}
#[test]
fn test_unordered_map_contains() {
let mut m = UnorderedMap::new();
m.insert(42, 99);
assert!(m.contains(&42));
assert!(!m.contains(&99));
}
#[test]
fn test_unordered_map_bucket_count() {
let mut m = UnorderedMap::new();
m.insert(1, 10);
assert!(m.bucket_count() > 0);
let lf = m.load_factor();
assert!(lf >= 0.0 && lf <= 1.0);
}
#[test]
fn test_unordered_map_rehash() {
let mut m = UnorderedMap::new();
m.rehash(100);
assert!(m.bucket_count() >= 100);
}
#[test]
fn test_unordered_map_reserve() {
let mut m = UnorderedMap::new();
m.reserve(50);
assert!(m.bucket_count() >= 50);
}
#[test]
fn test_unordered_map_get_or_default() {
let mut m = UnorderedMap::new();
let v = m.get_or_default(1, 42);
assert_eq!(*v, 42);
*v = 100;
assert_eq!(*m.find(&1).unwrap(), 100);
}
#[test]
fn test_unordered_set_new() {
let s: UnorderedSet<i32> = UnorderedSet::new();
assert!(s.empty());
}
#[test]
fn test_unordered_set_insert_contains() {
let mut s = UnorderedSet::new();
assert!(s.insert(1));
assert!(!s.insert(1)); assert!(s.contains(&1));
assert_eq!(s.size(), 1);
}
#[test]
fn test_unordered_set_erase() {
let mut s = UnorderedSet::new();
s.insert(1);
s.insert(2);
assert!(s.erase(&1));
assert!(!s.contains(&1));
assert_eq!(s.size(), 1);
}
#[test]
fn test_unordered_set_bucket_operations() {
let mut s = UnorderedSet::new();
s.insert(42);
assert!(s.bucket_count() > 0);
s.rehash(20);
assert!(s.bucket_count() >= 20);
}
#[test]
fn test_array_new() {
let a: StdArray<i32, 3> = StdArray::new();
assert_eq!(a.size(), 3);
assert!(!a.empty());
}
#[test]
fn test_array_from_array() {
let a = StdArray::from_array([10, 20, 30]);
assert_eq!(a[0], 10);
assert_eq!(a[1], 20);
assert_eq!(a[2], 30);
}
#[test]
fn test_array_front_back() {
let a = StdArray::from_array([1, 2, 3, 4, 5]);
assert_eq!(*a.front(), 1);
assert_eq!(*a.back(), 5);
}
#[test]
fn test_array_as_slice() {
let a = StdArray::from_array([1, 2, 3]);
let s = a.as_slice();
assert_eq!(s, &[1, 2, 3]);
}
#[test]
fn test_array_fill() {
let mut a = StdArray::from_array([0i32, 0, 0]);
a.fill(42);
assert_eq!(a[0], 42);
assert_eq!(a[1], 42);
assert_eq!(a[2], 42);
}
#[test]
fn test_array_swap() {
let mut a = StdArray::from_array([1, 2, 3]);
let mut b = StdArray::from_array([4, 5, 6]);
a.swap(&mut b);
assert_eq!(*a.as_slice(), [4, 5, 6]);
assert_eq!(*b.as_slice(), [1, 2, 3]);
}
#[test]
fn test_array_begin_end() {
let a = StdArray::from_array([1, 2, 3]);
let ptr = a.begin();
unsafe {
assert_eq!(*ptr, 1);
assert_eq!(*ptr.add(2), 3);
}
}
#[test]
fn test_stack_new() {
let s: Stack<i32> = Stack::new();
assert!(s.empty());
}
#[test]
fn test_stack_push_pop() {
let mut s = Stack::new();
s.push(1);
s.push(2);
s.push(3);
assert_eq!(s.size(), 3);
assert_eq!(s.top(), Some(&3));
assert_eq!(s.pop(), Some(3));
assert_eq!(s.pop(), Some(2));
assert_eq!(s.pop(), Some(1));
assert!(s.empty());
}
#[test]
fn test_stack_top_mut() {
let mut s = Stack::new();
s.push(10);
*s.top_mut().unwrap() = 20;
assert_eq!(s.top(), Some(&20));
}
#[test]
fn test_stack_swap() {
let mut a = Stack::new();
a.push(1);
let mut b = Stack::new();
b.push(2);
a.swap(&mut b);
assert_eq!(a.top(), Some(&2));
assert_eq!(b.top(), Some(&1));
}
#[test]
fn test_queue_new() {
let q: Queue<i32> = Queue::new();
assert!(q.empty());
}
#[test]
fn test_queue_push_pop() {
let mut q = Queue::new();
q.push(1);
q.push(2);
q.push(3);
assert_eq!(q.front(), Some(&1));
assert_eq!(q.back(), Some(&3));
assert_eq!(q.pop(), Some(1));
assert_eq!(q.pop(), Some(2));
assert_eq!(q.pop(), Some(3));
assert!(q.empty());
}
#[test]
fn test_queue_size() {
let mut q = Queue::new();
assert_eq!(q.size(), 0);
q.push(42);
assert_eq!(q.size(), 1);
}
#[test]
fn test_priority_queue_new() {
let pq: PriorityQueue<i32> = PriorityQueue::new();
assert!(pq.empty());
}
#[test]
fn test_priority_queue_push_pop() {
let mut pq = PriorityQueue::new();
pq.push(3);
pq.push(1);
pq.push(2);
assert_eq!(pq.top(), Some(&3));
assert_eq!(pq.pop(), Some(3));
assert_eq!(pq.pop(), Some(2));
assert_eq!(pq.pop(), Some(1));
}
#[test]
fn test_priority_queue_into_sorted() {
let mut pq = PriorityQueue::new();
pq.push(3);
pq.push(1);
pq.push(2);
let v = pq.into_sorted_vec();
assert_eq!(v, vec![3, 2, 1]);
}
#[test]
fn test_bitset_new() {
let bs = Bitset::<8>::new();
assert_eq!(bs.count(), 0);
assert!(bs.none());
assert!(!bs.any());
}
#[test]
fn test_bitset_set_test() {
let mut bs = Bitset::<8>::new();
bs.set(0, true);
bs.set(3, true);
bs.set(7, true);
assert!(bs.test(0));
assert!(!bs.test(1));
assert!(bs.test(3));
assert!(bs.test(7));
assert_eq!(bs.count(), 3);
}
#[test]
fn test_bitset_set_all() {
let mut bs = Bitset::<8>::new();
bs.set_all();
assert!(bs.all());
assert_eq!(bs.count(), 8);
}
#[test]
fn test_bitset_reset() {
let mut bs = Bitset::<8>::new();
bs.set_all();
bs.reset(0);
bs.reset(7);
assert!(!bs.test(0));
assert!(!bs.test(7));
assert_eq!(bs.count(), 6);
}
#[test]
fn test_bitset_flip() {
let mut bs = Bitset::<8>::new();
bs.set(0, true);
bs.flip(0);
assert!(!bs.test(0));
bs.flip(0);
assert!(bs.test(0));
bs.flip_all();
assert_eq!(bs.count(), 7); }
#[test]
fn test_bitset_to_string() {
let mut bs = Bitset::<4>::new();
bs.set(0, true);
bs.set(3, true);
assert_eq!(bs.to_string(), "1001");
}
#[test]
fn test_bitset_to_ulong() {
let mut bs = Bitset::<8>::new();
bs.set(0, true);
bs.set(1, true);
bs.set(2, true);
assert_eq!(bs.to_ulong(), Some(7));
}
#[test]
fn test_bitset_operators() {
let mut a = Bitset::<8>::new();
a.set(0, true);
a.set(1, true);
let mut b = Bitset::<8>::new();
b.set(1, true);
b.set(2, true);
let and = a.and(&b);
let or = a.or(&b);
let xor = a.xor(&b);
assert!(and.test(1));
assert!(!and.test(0));
assert!(or.test(0) && or.test(1) && or.test(2));
assert!(xor.test(0) && xor.test(2));
}
#[test]
fn test_bitset_shift() {
let mut bs = Bitset::<8>::new();
bs.set(1, true);
bs.set(2, true);
let left = bs.shift_left(1);
assert!(left.test(2));
assert!(left.test(3));
let right = bs.shift_right(1);
assert!(right.test(0));
assert!(right.test(1));
}
#[test]
fn test_valarray_new() {
let va = ValArray::<i32>::new();
assert_eq!(va.size(), 0);
}
#[test]
fn test_valarray_from_elem() {
let va = ValArray::from_elem(5, 42);
assert_eq!(va.size(), 5);
assert_eq!(va[0], 42);
assert_eq!(va[4], 42);
}
#[test]
fn test_valarray_sum() {
let va = ValArray::from_elem(3, 10i32);
assert_eq!(va.sum(), 30);
}
#[test]
fn test_valarray_min_max() {
let mut va = ValArray::new();
let vals = vec![3, 1, 4, 1, 5];
for v in vals {
va.resize(va.size() + 1, v);
}
let va = ValArray {
data: vec![3, 1, 4, 1, 5],
};
assert_eq!(*va.min().unwrap(), 1);
assert_eq!(*va.max().unwrap(), 5);
}
#[test]
fn test_valarray_apply() {
let va = ValArray {
data: vec![1, 2, 3],
};
let doubled = va.apply(|x| x * 2);
assert_eq!(*doubled.as_slice(), [2, 4, 6]);
}
#[test]
fn test_valarray_cshift() {
let va = ValArray {
data: vec![1, 2, 3, 4, 5],
};
let shifted = va.cshift(2);
assert_eq!(*shifted.as_slice(), [3, 4, 5, 1, 2]);
let shifted2 = va.cshift(-1);
assert_eq!(*shifted2.as_slice(), [5, 1, 2, 3, 4]);
}
#[test]
fn test_valarray_shift() {
let va = ValArray {
data: vec![1, 2, 3, 4, 5],
};
let shifted = va.shift(2);
assert_eq!(*shifted.as_slice(), [3, 4, 5, 0, 0]);
let shifted2 = va.shift(-2);
assert_eq!(*shifted2.as_slice(), [0, 0, 1, 2, 3]);
}
#[test]
fn test_valarray_arithmetic() {
let a = ValArray {
data: vec![1, 2, 3],
};
let b = ValArray {
data: vec![4, 5, 6],
};
let sum = &a + &b;
let diff = &a - &b;
let prod = &a * &b;
assert_eq!(*sum.as_slice(), [5, 7, 9]);
assert_eq!(*diff.as_slice(), [-3, -3, -3]);
assert_eq!(*prod.as_slice(), [4, 10, 18]);
}
#[test]
fn test_complex_new() {
let c = Complex::new(3.0, 4.0);
assert_eq!(*c.real(), 3.0);
assert_eq!(*c.imag(), 4.0);
}
#[test]
fn test_complex_abs() {
let c = Complex::new(3.0, 4.0);
assert!((c.abs() - 5.0).abs() < 0.001);
}
#[test]
fn test_complex_arg() {
let c = Complex::new(1.0, 1.0);
assert!((c.arg() - std::f64::consts::PI / 4.0).abs() < 0.001);
}
#[test]
fn test_complex_norm() {
let c = Complex::new(3.0, 4.0);
assert!((c.norm() - 25.0).abs() < 0.001);
}
#[test]
fn test_complex_conj() {
let c = Complex::new(3.0, 4.0);
let conj = c.conj();
assert_eq!(conj.re, 3.0);
assert_eq!(conj.im, -4.0);
}
#[test]
fn test_complex_add_sub_mul_div() {
let a = Complex::new(1.0, 2.0);
let b = Complex::new(3.0, 4.0);
let s = a + b;
assert_eq!(s.re, 4.0);
assert_eq!(s.im, 6.0);
let d = a - b;
assert_eq!(d.re, -2.0);
assert_eq!(d.im, -2.0);
let m = a * b;
assert_eq!(m.re, -5.0); assert_eq!(m.im, 10.0); let div = a / b;
assert!((div.re - 0.44).abs() < 0.01);
assert!((div.im - 0.08).abs() < 0.01);
}
#[test]
fn test_complex_polar() {
let c = Complex::polar(2.0, std::f64::consts::PI / 2.0);
assert!(c.re.abs() < 0.001);
assert!((c.im - 2.0).abs() < 0.001);
}
#[test]
fn test_complex_exp_sqrt() {
let c = Complex::new(1.0, 0.0);
let e = c.exp();
assert!((e.re - std::f64::consts::E).abs() < 0.001);
let s = Complex::new(4.0, 0.0).sqrt();
assert!((s.re - 2.0).abs() < 0.001);
}
#[test]
fn test_random_device() {
let rd = RandomDevice::new();
let val = rd.next_u32();
assert!(val >= rd.min() && val <= rd.max());
}
#[test]
fn test_mt19937_seeded() {
let mut mt = Mt19937::new(42);
let val1 = mt.next_u32();
let mut mt2 = Mt19937::new(42);
let val2 = mt2.next_u32();
assert_eq!(val1, val2); }
#[test]
fn test_mt19937_many() {
let mut mt = Mt19937::new(12345);
for _ in 0..1000 {
let _ = mt.next_u32();
}
}
#[test]
fn test_uniform_int_distribution() {
let mut gen = Mt19937::new(42);
let dist = UniformIntDistribution::new(1, 6);
for _ in 0..100 {
let val = dist.sample(&mut gen);
assert!(val >= 1 && val <= 6);
}
}
#[test]
fn test_uniform_real_distribution() {
let mut gen = Mt19937::new(42);
let dist = UniformRealDistribution::new(0.0, 1.0);
for _ in 0..100 {
let val = dist.sample(&mut gen);
assert!(val >= 0.0 && val < 1.0);
}
}
#[test]
fn test_normal_distribution() {
let mut gen = Mt19937::new(42);
let mut dist = NormalDistribution::new(0.0, 1.0);
let mut sum = 0.0;
let n = 1000;
for _ in 0..n {
sum += dist.sample(&mut gen);
}
let mean = sum / n as f64;
assert!(mean.abs() < 0.5);
}
#[test]
fn test_bernoulli_distribution() {
let mut gen = Mt19937::new(42);
let dist = BernoulliDistribution::new(0.7);
let mut trues = 0;
let n = 1000;
for _ in 0..n {
if dist.sample(&mut gen) {
trues += 1;
}
}
let ratio = trues as f64 / n as f64;
assert!((ratio - 0.7).abs() < 0.1);
}
#[test]
fn test_duration_helpers() {
let h = hours(1);
let m = minutes(60);
let s = seconds(3600);
assert_eq!(h, m);
assert_eq!(m, s);
assert_eq!(s.count(), 3_600_000_000_000);
}
#[test]
fn test_duration_arithmetic() {
let a = seconds(10);
let b = seconds(5);
assert_eq!((a + b).count(), seconds(15).count());
assert_eq!((a - b).count(), seconds(5).count());
}
#[test]
fn test_system_clock_now() {
let tp = SystemClock::now();
assert!(tp.nanos_since_epoch > 0);
}
#[test]
fn test_system_clock_to_from_time_t() {
let t = 1_700_000_000i64;
let tp = SystemClock::from_time_t(t);
assert_eq!(SystemClock::to_time_t(&tp), t);
assert_eq!(tp.time_since_epoch(), seconds(t));
}
#[test]
fn test_time_point_arithmetic() {
let tp = TimePoint::from_nanos(1_000_000_000);
let later = tp + seconds(10);
let diff = later - tp;
assert_eq!(diff, seconds(10));
}
#[test]
fn test_thread_hardware_concurrency() {
let n = CxxThread::hardware_concurrency();
assert!(n >= 1);
}
#[test]
fn test_thread_yield() {
CxxThread::yield_now();
}
#[test]
fn test_thread_sleep_for() {
CxxThread::sleep_for(Duration::from_millis(1));
}
#[test]
fn test_thread_join() {
let mut counter = 0;
let mut t = CxxThread::new(|| {
for _ in 0..100 {
}
});
assert!(t.joinable());
t.join();
}
#[test]
fn test_mutex_lock() {
let m = CxxMutex::new(42);
{
let guard = m.lock();
assert_eq!(*guard, 42);
}
let guard = m.lock();
assert_eq!(*guard, 42);
}
#[test]
fn test_mutex_try_lock() {
let m = CxxMutex::new(10);
{
let _guard = m.lock();
assert!(m.try_lock().is_none());
}
assert!(m.try_lock().is_some());
}
#[test]
fn test_lock_guard() {
let m = CxxMutex::new(100);
{
let _lg = LockGuard::new(&m);
}
let g = m.lock();
assert_eq!(*g, 100);
}
#[test]
fn test_unique_lock() {
let m = CxxMutex::new(200);
let mut ul = UniqueLock::new(&m);
assert!(ul.owns_lock());
*ul = 300;
ul.unlock();
assert!(!ul.owns_lock());
drop(ul);
let g = m.lock();
assert_eq!(*g, 300);
}
#[test]
fn test_condition_variable() {
let cv = ConditionVariable::new();
cv.notify_one();
cv.notify_all();
}
#[test]
fn test_atomic_i32_load_store() {
let mut a = Atomic::<i32>::new(42);
assert_eq!(a.load(), 42);
a.store(100);
assert_eq!(a.load(), 100);
}
#[test]
fn test_atomic_i32_exchange() {
let mut a = Atomic::<i32>::new(10);
let old = a.exchange(20);
assert_eq!(old, 10);
assert_eq!(a.load(), 20);
}
#[test]
fn test_atomic_i32_compare_exchange() {
let mut a = Atomic::<i32>::new(42);
let mut expected = 42;
assert!(a.compare_exchange_strong(&mut expected, 100).is_ok());
assert_eq!(a.load(), 100);
expected = 42;
assert!(a.compare_exchange_strong(&mut expected, 200).is_err());
assert_eq!(expected, 100); }
#[test]
fn test_atomic_i32_fetch_add_sub() {
let mut a = Atomic::<i32>::new(10);
assert_eq!(a.fetch_add(5), 10);
assert_eq!(a.load(), 15);
assert_eq!(a.fetch_sub(3), 15);
assert_eq!(a.load(), 12);
}
#[test]
fn test_atomic_u32() {
let mut a = Atomic::<u32>::new_u32(100);
assert_eq!(a.load(), 100);
assert_eq!(a.fetch_add(50), 100);
assert_eq!(a.load(), 150);
}
#[test]
fn test_atomic_u64() {
let mut a = Atomic::<u64>::new_u64(1000);
assert_eq!(a.load(), 1000);
a.store(2000);
assert_eq!(a.load(), 2000);
}
#[test]
fn test_atomic_bool() {
let mut a = Atomic::<bool>::new_bool(false);
assert!(!a.load());
a.store(true);
assert!(a.load());
assert!(a.exchange(false));
assert!(!a.load());
}
#[test]
fn test_fs_path_new() {
let p = FsPath::new("/usr/local/bin");
assert_eq!(p.to_string(), "/usr/local/bin");
}
#[test]
fn test_fs_path_filename() {
let p = FsPath::new("/usr/local/bin/gcc");
assert_eq!(p.filename().unwrap().to_string(), "gcc");
}
#[test]
fn test_fs_path_extension() {
let p = FsPath::new("file.txt");
assert_eq!(p.extension(), Some("txt".to_string()));
}
#[test]
fn test_fs_path_stem() {
let p = FsPath::new("file.txt");
assert_eq!(p.stem(), Some("file".to_string()));
}
#[test]
fn test_fs_path_parent() {
let p = FsPath::new("/usr/local/bin/gcc");
assert_eq!(p.parent_path().unwrap().to_string(), "/usr/local/bin");
}
#[test]
fn test_fs_path_is_absolute_relative() {
let abs = FsPath::new("/usr/bin");
let rel = FsPath::new("usr/bin");
assert!(abs.is_absolute());
assert!(!abs.is_relative());
assert!(rel.is_relative());
assert!(!rel.is_absolute());
}
#[test]
fn test_fs_path_empty() {
let p = FsPath::new("");
assert!(p.empty());
let p2 = FsPath::new("/");
assert!(!p2.empty());
}
#[test]
fn test_fs_path_div() {
let p = FsPath::new("/usr");
let child = &p / "local";
assert_eq!(child.to_string(), "/usr/local");
}
#[test]
fn test_fs_path_append() {
let mut p = FsPath::new("/usr");
p.append("local");
p.append("bin");
assert_eq!(p.to_string(), "/usr/local/bin");
}
#[test]
fn test_fs_path_replace_extension() {
let mut p = FsPath::new("file.cpp");
p.replace_extension("o");
assert_eq!(p.to_string(), "file.o");
}
#[test]
fn test_fs_path_current_path() {
let cwd = FsPath::current_path();
assert!(cwd.is_some());
}
#[test]
fn test_fs_path_temp_directory() {
let tmp = FsPath::temp_directory_path();
assert!(!tmp.empty());
}
#[test]
fn test_fs_path_create_remove_directory() {
let tmp = FsPath::temp_directory_path();
let test_dir = &tmp / "llvm_native_test_fs";
let _ = test_dir.remove_all();
assert!(test_dir.create_directory().is_ok());
assert!(test_dir.is_directory());
assert!(test_dir.exists());
assert!(test_dir.remove().is_ok());
assert!(!test_dir.exists());
}
#[test]
fn test_fs_path_write_read() {
let tmp = FsPath::temp_directory_path();
let test_file = &tmp / "llvm_native_test_fs.txt";
assert!(test_file.write_string("hello world").is_ok());
assert!(test_file.exists());
assert!(test_file.is_regular_file());
let content = test_file.read_to_string().unwrap();
assert_eq!(content, "hello world");
let _ = test_file.remove();
}
}