use std::iter;
use std::ops;
use std::convert;
use std::cmp;
use std::fmt;
use lazy::Lazy;
use finger_tree;
use finger_tree::FingerTree;
use node;
use measure::Measure;
#[derive(Debug)]
struct Item<T>(T);
impl<T> Measure<usize> for Item<T> {
fn measure(&self) -> usize {1}
}
pub struct Seq<T> (Lazy<FingerTree<Item<T>,usize>>);
impl<T:'static> Seq<T> {
pub fn empty() -> Seq<T> {
Seq(finger_tree::empty())
}
pub fn singleton(x: T) -> Seq<T> {
Seq(finger_tree::single(node::leaf(Item(x))))
}
pub fn push_front(&self, x: T) -> Seq<T> {
Seq(finger_tree::cons_node(node::leaf(Item(x)), self.inner().clone()))
}
pub fn push_back(&self, x: T) -> Seq<T> {
Seq(finger_tree::snoc_node(self.inner().clone(), node::leaf(Item(x))))
}
pub fn append(&self, other: &Seq<T>) -> Seq<T> {
Seq(finger_tree::tree_tree(self.inner().clone(), other.inner().clone()))
}
pub fn is_empty(&self) -> bool {
self.inner().measure() == 0
}
pub fn len(&self) -> usize {
self.inner().measure()
}
pub fn front(&self) -> Option<&T> {
finger_tree::front(self.inner()).map(|&Item(ref x)| x)
}
pub fn back(&self) -> Option<&T> {
finger_tree::back(self.inner()).map(|&Item(ref x)| x)
}
pub fn pop_front(&self) -> Seq<T> {
Seq(finger_tree::pop_front(self.inner()))
}
pub fn pop_back(&self) -> Seq<T> {
Seq(finger_tree::pop_back(self.inner()))
}
pub fn adjust<F>(&self, i: usize, func: F) -> Seq<T>
where F: FnOnce(&T) -> T
{
if i >= self.len() {
return self.clone()
}
Seq(finger_tree::adjust(move |&Item(ref x)| Item(func(x)), move |j| {i < j}, 0, self.inner()))
}
pub fn update(&self, i: usize, x: T) -> Seq<T> {
self.adjust(i, move |_| x)
}
pub fn truncate(&self, count: usize) -> Seq<T> {
let (before,_) = self.split(count);
before
}
pub fn skip(&self, count: usize) -> Seq<T> {
let (_,after) = self.split(count);
after
}
pub fn split(&self, n: usize) -> (Seq<T>, Seq<T>) {
if n >= self.len() {
return (self.clone(), Seq::empty())
}
let (before,x,after) = finger_tree::split(&move |i| {n < i}, 0, self.inner());
(Seq(before), Seq(finger_tree::cons_node(x.clone(), after)))
}
pub fn remove(&self, i: usize) -> Seq<T> {
if i >= self.len() {
return self.clone()
}
let (before,_,after) = finger_tree::split(&move |j| {i < j}, 0, self.inner());
Seq(finger_tree::tree_tree(before, after))
}
pub fn insert(&self, i: usize, x: T) -> Seq<T> {
if i >= self.len() {
return self.push_back(x)
}
let (before,y,after) = finger_tree::split(&move |j| {i < j}, 0, self.inner());
let before = finger_tree::snoc_node(before, node::leaf(Item(x)));
let after = finger_tree::cons_node(y.clone(), after);
Seq(finger_tree::tree_tree(before, after))
}
pub fn get(&self, i: usize) -> Option<&T> {
if i >= self.len() {
return None
}
match finger_tree::lookup(move |j| {i < j}, 0, self.inner()) {
(&Item(ref x), _) => Some(x)
}
}
pub fn iter(&self) -> Iter<T> {
self.into_iter()
}
fn inner(&self) -> &Lazy<FingerTree<Item<T>,usize>> {
match *self {
Seq(ref inner) => inner
}
}
}
#[macro_export]
macro_rules! seq {
() => {
$crate::Seq::empty()
};
($e0: expr $(, $e: expr)*) => {
seq!($($e),*).push_front($e0)
};
($e: expr ; $n: expr) => {
::std::iter::repeat($e).take($n).collect::<$crate::Seq<_>>()
};
}
impl<T:'static> Clone for Seq<T> {
fn clone(&self) -> Seq<T> {
Seq(self.inner().clone())
}
}
impl<T:'static> PartialEq for Seq<T>
where T: PartialEq
{
fn eq(&self, other: &Seq<T>) -> bool {
self.iter().eq(other.iter())
}
}
impl<T:'static> Eq for Seq<T>
where T: Eq
{}
impl<T:'static> PartialOrd for Seq<T>
where T: PartialOrd
{
fn partial_cmp(&self, other: &Seq<T>) -> Option<cmp::Ordering> {
self.iter().partial_cmp(other.iter())
}
}
impl<T:'static> Ord for Seq<T>
where T: Ord
{
fn cmp(&self, other: &Seq<T>) -> cmp::Ordering {
self.iter().cmp(other.iter())
}
}
impl<T:'static> fmt::Debug for Seq<T>
where T: fmt::Debug
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_list().entries(self.iter()).finish()
}
}
#[derive(Debug)]
pub struct Iter<'a, T: 'a> {
inner: finger_tree::Iter<'a, Item<T>, usize>
}
impl<'a,T:'static> Iter<'a,T> {
fn new(seq: &'a Seq<T>) -> Iter<'a,T> {
Iter {
inner: seq.inner().iter()
}
}
}
impl<'a,T:'a> Iterator for Iter<'a,T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
match self.inner.next() {
None => None,
Some(&Item(ref x)) => Some(x)
}
}
}
impl<'a, T: 'static> iter::IntoIterator for &'a Seq<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a,T> {
Iter::new(self)
}
}
impl<T:'static> iter::FromIterator<T> for Seq<T> {
fn from_iter<I>(iter: I) -> Self
where I: IntoIterator<Item=T> {
let mut iter = iter.into_iter();
let mut seq = Seq::empty();
while let Some(x) = iter.next() {
seq = seq.push_back(x);
}
seq
}
}
impl<T:'static> convert::From<Vec<T>> for Seq<T> {
fn from(v: Vec<T>) -> Seq<T> {
v.into_iter().collect()
}
}
impl<T:'static> ops::Index<usize> for Seq<T> {
type Output = T;
fn index(&self, index: usize) -> &T {
self.get(index).expect("Out of bounds access")
}
}