use std::fmt::{Debug, Write};
use std::iter::FromIterator;
use std::ops::{Index, IndexMut, Range};
pub trait Sequence<Item, Subsequence: Sequence<Item, Subsequence> + ?Sized>:
Index<usize, Output = Item> + Index<Range<usize>, Output = Subsequence>
{
type Iterator<'a>: DoubleEndedIterator<Item = &'a Item>
where
Self: 'a,
Item: 'a;
fn prefix(&self, len: usize) -> &Subsequence {
debug_assert!(len < self.len());
&self[0..len]
}
fn suffix(&self, len: usize) -> &Subsequence {
debug_assert!(len < self.len());
&self[self.len() - len..self.len()]
}
fn iter(&self) -> Self::Iterator<'_>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn first(&self) -> Option<&Item> {
self.iter().next()
}
fn last(&self) -> Option<&Item> {
self.iter().last()
}
fn is_proper_subsequence_of(&self, other: &Self) -> bool
where
Item: Eq,
{
if self.len() >= other.len() {
return false;
}
for start_index in 0..=other.len() - self.len() {
let mut found_subsequence = true;
for index in 0..self.len() {
if self[index] != other[start_index + index] {
found_subsequence = false;
break;
}
}
if found_subsequence {
return true;
}
}
false
}
fn contains(&self, item: &Item) -> bool
where
Item: Eq,
{
self.iter().any(|i| item == i)
}
fn forward_merge_iter_assume_mergeable<'a>(
&'a self,
suffix: &'a Self,
) -> std::iter::Chain<Self::Iterator<'a>, std::iter::Skip<Self::Iterator<'a>>>
where
Item: Eq,
{
let first_item_index = self
.iter()
.enumerate()
.filter(|(_, i)| *i == suffix.first().expect("The given sequence is empty."))
.map(|(i, _)| i)
.next()
.expect("This sequence does not contain the first item of the given sequence.");
self.iter()
.chain(suffix.iter().skip(self.len() - first_item_index))
}
fn backward_merge_iter_assume_mergeable<'a>(
&'a self,
suffix: &'a Self,
) -> std::iter::Chain<Self::Iterator<'a>, std::iter::Skip<Self::Iterator<'a>>>
where
Item: Eq,
{
suffix.forward_merge_iter_assume_mergeable(self)
}
fn to_debug_string(&self) -> String
where
Item: Debug,
{
let mut result = String::new();
write!(result, "[").unwrap();
let mut once = true;
for item in self.iter() {
if once {
once = false;
} else {
write!(result, ", ").unwrap();
}
write!(result, "{:?}", item).unwrap();
}
write!(result, "]").unwrap();
result
}
}
pub trait SequenceMut<Item, Subsequence: SequenceMut<Item, Subsequence> + ?Sized>:
Sequence<Item, Subsequence>
+ IndexMut<usize, Output = Item>
+ IndexMut<Range<usize>, Output = Subsequence>
{
type IteratorMut<'a>: Iterator<Item = &'a mut Item>
where
Self: 'a,
Item: 'a;
fn iter_mut(&mut self) -> Self::IteratorMut<'_>;
}
pub trait OwnedSequence<Item, Subsequence: Sequence<Item, Subsequence> + ?Sized>:
Sequence<Item, Subsequence> + Sized
{
}
pub trait CloneableSequence<Item: Clone, Subsequence: CloneableSequence<Item, Subsequence> + ?Sized>:
ToOwned
{
}
pub trait EditableSequence<Item, Subsequence: Sequence<Item, Subsequence> + ?Sized>:
Sequence<Item, Subsequence> + Extend<Item> + IntoIterator<Item = Item> + FromIterator<Item>
{
fn set(&mut self, index: usize, item: Item);
fn split_off(&mut self, at: usize) -> Self;
fn extend_into<
ExtensionItem: Into<Item>,
ExtensionSource: IntoIterator<Item = ExtensionItem>,
>(
&mut self,
extension: ExtensionSource,
) {
self.extend(extension.into_iter().map(Into::into));
}
fn reserve(&mut self, additional: usize);
fn resize(&mut self, new_len: usize, value: Item)
where
Item: Clone;
fn resize_with(&mut self, new_len: usize, generator: impl FnMut() -> Item);
fn push(&mut self, item: Item);
fn delete(&mut self, range: Range<usize>)
where
Item: Clone,
{
assert!(range.end <= self.len());
if range.start >= range.end {
assert_eq!(range.start, range.end);
} else {
for index in range.start..self.len() - range.len() {
self.set(index, self[index + range.len()].clone());
}
self.resize_with(self.len() - range.len(), || unreachable!());
}
}
fn insert_repeat(&mut self, source_range: Range<usize>, target: usize)
where
Item: Clone,
{
assert!(source_range.end <= self.len());
if source_range.start >= source_range.end {
assert_eq!(source_range.start, source_range.end);
} else {
self.resize(self.len() + source_range.len(), self[0].clone());
for index in (target + source_range.len()..self.len() + source_range.len()).rev() {
self.set(index, self[index - source_range.len()].clone());
}
for index in 0..source_range.len() {
if index + source_range.start < target {
self.set(index + target, self[index + source_range.start].clone());
} else {
self.set(index + target, self[index + source_range.end].clone());
}
}
}
}
fn splice(&mut self, range: Range<usize>, replace_with: impl IntoIterator<Item = Item>);
}
#[cfg(test)]
mod tests {
use crate::interface::Sequence;
#[test]
fn test_merge_sequences_simple() {
let s1 = vec![0, 1, 2, 3, 4, 5];
let s2 = vec![3, 4, 5, 6, 7, 8];
let merged: Vec<_> = s1
.forward_merge_iter_assume_mergeable(&s2)
.copied()
.collect();
debug_assert_eq!(merged, vec![0, 1, 2, 3, 4, 5, 6, 7, 8]);
}
}