use std::cmp::Ordering;
use std::fmt::{Debug, Formatter};
use std::ops::{Add, AddAssign};
use std::ops::{Index, IndexMut};
use num_integer::gcd;
#[cfg(feature = "serde-derive")]
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde-derive", derive(Serialize, Deserialize))]
pub struct Node<T> {
position: Pos,
element: Option<T>,
}
impl<T> Node<T> {
#[inline]
#[must_use]
fn new(position: Pos, element: T) -> Self {
Node {
position,
element: Some(element),
}
}
#[inline]
#[must_use]
fn new_empty(position: Pos) -> Self {
Node { position, element: None }
}
#[inline]
#[must_use]
fn position(&self) -> Pos {
self.position
}
#[inline]
#[must_use]
pub fn pos(&self) -> (u64, u64) {
(self.position.num, self.position.denom)
}
#[inline]
#[must_use]
pub fn num(&self) -> u64 {
self.position.num
}
#[inline]
#[must_use]
pub fn denom(&self) -> u64 {
self.position.denom
}
#[inline]
#[must_use]
pub fn element(self) -> Option<T> {
self.element
}
#[inline]
#[must_use]
pub fn element_as_ref(&self) -> Option<&T> {
self.element.as_ref()
}
#[inline]
#[must_use]
pub fn element_as_mut(&mut self) -> Option<&mut T> {
self.element.as_mut()
}
#[inline]
#[must_use]
pub fn is_none(&self) -> bool {
self.element.is_none()
}
#[inline]
#[must_use]
pub fn is_some(&self) -> bool {
self.element.is_some()
}
#[inline]
fn set(&mut self, element: T) {
self.element = Some(element)
}
}
#[cfg(test)]
#[path = "tests/node_tests.rs"]
mod node_tests;
const DENOM_MIN: u64 = 1;
#[derive(Copy, Clone)]
#[cfg_attr(feature = "serde-derive", derive(Serialize, Deserialize))]
pub struct Pos {
num: u64,
denom: u64,
}
trait Min {
const MIN: Pos;
}
impl Min for Pos {
const MIN: Pos = Pos { num: u64::MIN, denom: 1 };
}
trait Max {
const MAX: Pos;
}
impl Max for Pos {
const MAX: Pos = Pos { num: u64::MAX, denom: 1 };
}
impl Pos {
#[inline]
#[must_use]
fn new(num: u64, denom: u64) -> Self {
if denom < DENOM_MIN {
Pos { num, denom: DENOM_MIN }
} else {
Pos { num, denom }
}
}
#[inline]
#[must_use]
fn n1d0() -> Self {
Self { num: 1, denom: 0 }
}
#[inline]
#[must_use]
fn mid(first: Self, second: Self) -> Self {
first + second
}
}
impl Add for Pos {
type Output = Self;
#[inline]
#[must_use]
fn add(self, rhs: Self) -> Self::Output {
Self {
num: self.num + rhs.num,
denom: self.denom + rhs.denom,
}
}
}
impl AddAssign for Pos {
#[inline]
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl PartialEq for Pos {
#[inline]
fn eq(&self, other: &Self) -> bool {
if self.num == other.num && self.denom == other.denom {
true
} else {
let self_divisor = gcd(self.num, self.denom);
let other_divisor = gcd(other.num, other.denom);
match (self_divisor, other_divisor) {
(1, 1) => false,
#[rustfmt::skip]
(_, 1) => { let f1 = Self::new(self.num / self_divisor, self.denom / self_divisor);
f1 == *other
}
#[rustfmt::skip]
(1, _) => { let f2 = Self::new(other.num / other_divisor, other.denom / other_divisor);
f2 == *self
}
#[rustfmt::skip]
(_, _) => { let f1 = Self::new(self.num / self_divisor, self.denom / self_divisor);
let f2 = Self::new(other.num / other_divisor, other.denom / other_divisor);
f1 == f2
}
}
}
}
}
impl PartialOrd for Pos {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let f1 = self.num as f64 / self.denom as f64;
let f2 = other.num as f64 / self.denom as f64;
f1.partial_cmp(&f2)
}
}
impl Debug for Pos {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}/{} ({})", self.num, self.denom, self.num as f64 / self.denom as f64)
}
}
impl Default for Pos {
#[inline]
#[must_use]
fn default() -> Self {
Self::new(1, DENOM_MIN)
}
}
#[cfg(test)]
#[path = "tests/position_tests.rs"]
mod position_tests;
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "serde-derive", derive(Serialize, Deserialize))]
pub struct Sequence<T> {
nodes: Vec<Node<T>>,
len: usize,
}
impl<T> Sequence<T> {
#[inline]
#[must_use]
pub fn new() -> Self {
Self {
nodes: Vec::new(),
len: 0,
}
}
#[inline]
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
nodes: Vec::with_capacity(capacity),
len: 0,
}
}
#[inline]
pub fn capacity(&self) -> usize {
self.nodes.capacity()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
#[must_use]
pub fn first(&self) -> Option<&T> {
if self.len == 0 {
return None;
}
for node in self.nodes.iter() {
if node.is_some() {
return node.element_as_ref();
}
}
#[cfg(not(tarpaulin_include))]
{
None
}
}
#[inline]
#[must_use]
pub fn last(&self) -> Option<&T> {
if self.len == 0 {
return None;
}
for node in self.nodes.iter().rev() {
if node.is_some() {
return node.element_as_ref();
}
}
#[cfg(not(tarpaulin_include))]
{
None
}
}
#[inline]
#[must_use]
pub fn get(&self, index: usize) -> Option<&T> {
if index >= self.len {
return None;
}
for node in self.nodes[index..].iter() {
if node.is_some() {
return node.element_as_ref();
}
}
#[cfg(not(tarpaulin_include))]
{
None
}
}
#[inline]
#[must_use]
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
if index >= self.len {
return None;
}
for node in self.nodes[index..].iter_mut() {
if node.is_some() {
return node.element_as_mut();
}
}
#[cfg(not(tarpaulin_include))]
{
None
}
}
pub fn index_from(&self, position: Pos) -> Option<usize> {
self.nodes.iter().position(|node| node.position() == position)
}
pub fn insert(&mut self, index: usize, element: T) {
if index >= self.nodes.len() {
self.push(element);
} else {
if self.nodes[index].is_some() {
let pos = if index == 0 {
Pos::mid(Pos::MIN, self.nodes.first().map(|node| node.position()).unwrap())
} else {
Pos::mid(
self.nodes.get(index - 1).map(|node| node.position()).unwrap(),
self.nodes.get(index).map(|node| node.position()).unwrap(),
)
};
let node = Node::new(pos, element);
self.nodes.insert(index, node);
} else {
self.nodes[index].set(element);
}
self.len += 1;
}
}
pub fn insert_at(&mut self, position: Pos, element: T) {
match self.index_from(position) {
None => {
let index = self.nodes.partition_point(|node| node.position() < position);
self.insert(index, element);
}
Some(index) => {
if self.nodes[index].is_none() {
self.len += 1;
}
self.nodes[index].set(element);
}
}
}
pub fn position_from(&self, index: usize) -> Option<Pos> {
if index >= self.nodes.len() {
None
} else {
Some(self.nodes[index].position())
}
}
#[allow(unused)]
fn pos_from(&self, index: usize) -> Option<(u64, u64)> {
if index >= self.nodes.len() {
None
} else {
Some(self.nodes[index].pos())
}
}
#[inline]
pub fn push(&mut self, element: T) {
let pos = match self.last_position() {
None => Pos::new(1, 1),
Some(pos) => pos + Pos::n1d0(),
};
let node = Node::new(pos, element);
self.nodes.push(node);
self.len += 1;
}
pub fn remove(&mut self, index: usize) -> Option<T> {
if index >= self.len {
return None;
}
for (i, node) in self.nodes[index..].iter().enumerate() {
if node.is_some() {
self.len -= 1;
let node = Node::new_empty(self.nodes[index + i].position());
self.nodes.push(node);
return self.nodes.swap_remove(index + i).element();
}
}
#[cfg(not(tarpaulin_include))]
{
None
}
}
pub fn remove_at(&mut self, position: Pos) -> Option<T> {
match self.index_from(position) {
None => None,
Some(index) => self.remove(index),
}
}
#[inline]
#[must_use]
fn last_position(&self) -> Option<Pos> {
self.nodes.last().map(|node| node.position())
}
#[cfg(not(tarpaulin_include))]
#[allow(dead_code)]
fn shrink(&mut self) {
unimplemented!()
}
}
impl<T> Default for Sequence<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Index<usize> for Sequence<T> {
type Output = Node<T>;
#[inline]
fn index(&self, index: usize) -> &Self::Output {
&self.nodes[index]
}
}
impl<T> IndexMut<usize> for Sequence<T> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.nodes[index]
}
}
impl<T: Clone> Clone for Sequence<T> {
fn clone(&self) -> Self {
let mut seq: Sequence<T> = Sequence::new();
for node in self {
let node = match node.element_as_ref() {
None => Node::new_empty(node.position()),
Some(element) => Node::new(node.position(), element.clone()),
};
seq.nodes.push(node);
}
seq.len = self.len;
seq
}
}
impl<T> IntoIterator for Sequence<T> {
type Item = Node<T>;
type IntoIter = std::vec::IntoIter<Node<T>>;
#[inline]
fn into_iter(mut self) -> Self::IntoIter {
self.nodes.retain(|node| node.element_as_ref().is_some());
self.nodes.into_iter()
}
}
pub struct SequenceIterator<'iterator, T: 'iterator>(Option<&'iterator [Node<T>]>);
impl<'iterator, T: 'iterator> Iterator for SequenceIterator<'iterator, T> {
type Item = &'iterator Node<T>;
fn next(self: &'_ mut SequenceIterator<'iterator, T>) -> Option<Self::Item> {
self.0.and_then(|v| {
let (head, tail) = v.split_first()?;
self.0 = Some(tail);
Some(head)
})
}
}
impl<'iterator, T: 'iterator> IntoIterator for &'iterator Sequence<T> {
type Item = &'iterator Node<T>;
type IntoIter = SequenceIterator<'iterator, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
SequenceIterator(Some(self.nodes.as_slice()))
}
}
pub struct SequenceIteratorMut<'iterator, T: 'iterator>(Option<&'iterator mut [Node<T>]>);
impl<'iterator, T: 'iterator> Iterator for SequenceIteratorMut<'iterator, T> {
type Item = &'iterator mut Node<T>;
fn next(self: &'_ mut SequenceIteratorMut<'iterator, T>) -> Option<Self::Item> {
self.0.take().and_then(|v| {
let (head, tail) = v.split_first_mut()?;
self.0 = Some(tail);
Some(head)
})
}
}
impl<'iterator, T: 'iterator> IntoIterator for &'iterator mut Sequence<T> {
type Item = &'iterator mut Node<T>;
type IntoIter = SequenceIteratorMut<'iterator, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
SequenceIteratorMut(Some(self.nodes.as_mut_slice()))
}
}
#[cfg(test)]
#[path = "tests/sequence_tests.rs"]
mod sequence_tests;