qcollect 0.3.0

Collections; Collection-Traits.
use traits::*;

use std::borrow::Borrow;
use std::{cmp, iter};

/// NOTE `T` currently needs to be 'static. 
///       This will get fixed when qcollect-traits gets fixed.
///
/// TODO Can we make `C` be `?Sized`?
///
/// TODO export trait-methods to impl. requires mutally exclusive traits
pub struct ByValue<C> 
    //where C: ImmutableCollection, FIXME uncomment this
{
    inner: C,
}

impl<C> From<C> for ByValue<C>
    where C: ImmutableCollection,
{
    fn from(inner: C) -> Self { ByValue{ inner: inner } }
}

impl<C> ByValue<C>
    where C: ImmutableCollection,
{
    pub fn new(inner: C) -> Self {
        Self::from(inner)
    }

    pub fn into_inner(self) -> C { self.inner }

    pub fn len(&self) -> usize { self.inner.len() }
    pub fn is_empty(&self) -> bool { self.inner.is_empty() }
}

impl<C> ByValue<C>
    where C: GrowableCollection,
{
    pub fn capacity(&self) -> usize { self.inner.capacity() }
    pub fn reserve(&mut self, n: usize){ self.inner.reserve(n); }
    pub fn reserve_exact(&mut self, n: usize){ self.inner.reserve_exact(n); }
    pub fn clear(&mut self){ self.inner.clear(); }
}

// ++++++++++++++++++++ QCollect/Base Traits ++++++++++++++++++++

impl<C> ImmutableCollection for ByValue<C>
    where C: ImmutableCollection
{
    fn len(&self) -> usize { self.inner.len() }
    fn is_empty(&self) -> bool { self.inner.is_empty() }
}

impl<C> MutableCollection for ByValue<C>
    where C: MutableCollection
{}

impl<C> GrowableCollection for ByValue<C>
    where C: GrowableCollection
{
    fn capacity(&self) -> usize { self.inner.capacity() }
    fn reserve(&mut self, n: usize) { self.inner.reserve(n); }
    fn reserve_exact(&mut self, n: usize) { self.inner.reserve_exact(n); }
    fn clear(&mut self){ self.inner.clear(); }
}

// ++++++++++++++++++++ QCollect/Sequence-traits ++++++++++++++++++++

impl<'a, T, C> ImmutableSequenceTypes<'a, T> for ByValue<C>
    where T: Copy + 'static, C: ImmutableSequenceTypes<'a, T, Output = &'a T>
{
    type Output = T;
    type Iter = iter::Cloned<C::Iter>;
}

impl<T, C> ImmutableSequence<T> for ByValue<C>
where 
    T: Copy + 'static, 
    C: ImmutableSequence<T> + for<'a> ImmutableSequenceTypes<'a, T, Output = &'a T>
{
    fn get<'a>(&'a self, idx: usize) -> Option<T> { 
        self.inner.get(idx).map(|r| *r)
    }

    fn iter<'a>(&'a self) -> <Self as ImmutableSequenceTypes<'a, T>>::Iter{ 
        self.inner.iter().cloned()
    }
}

impl<'a, T, C> MutableSequenceTypes<'a, T> for ByValue<C>
    where T: Copy + 'static, C: MutableSequenceTypes<'a, T, Output = &'a T>
{
    type IterMut = IterMutDummy<&'a mut T>;
}

impl<T, C> MutableSequence<T> for ByValue<C>
where 
    T: Copy + 'static, 
    C: MutableSequence<T> + for<'a> MutableSequenceTypes<'a, T, Output = &'a T>
{
    fn swap(&mut self, a: usize, b: usize){ self.inner.swap(a, b); }

    fn sort_by<F>(&mut self, compare: F)
        where F: FnMut(&T, &T) -> cmp::Ordering
    { self.inner.sort_by(compare); }

    fn sort(&mut self)
        where T: Ord
    { self.inner.sort(); }
}

impl<T, C> GrowableSequence<T> for ByValue<C>
where 
    T: Copy + 'static, 
    C: GrowableSequence<T> + for<'a> MutableSequenceTypes<'a, T, Output = &'a T>
{
    fn insert(&mut self, idx: usize, val: T){ self.inner.insert(idx, val); }
    fn remove(&mut self, idx: usize) -> T { self.inner.remove(idx) }
    fn push(&mut self, val: T){ self.inner.push(val); }
    fn pop(&mut self) -> Option<T> { self.inner.pop() }
}

// ++++++++++++++++++++ QCollect/Set-traits ++++++++++++++++++++

impl<'a, T, C> ImmutableSetTypes<'a, T> for ByValue<C>
    where T: Copy + 'static, C: ImmutableSetTypes<'a, T, Output = &'a T>
{
    type Output = T;
    type Iter = iter::Cloned<C::Iter>;
}

impl<T, Q: ?Sized, C> ImmutableSet<T, Q> for ByValue<C>
where 
    T: Borrow<Q> + Copy + 'static,
    C: ImmutableSet<T, Q> + for<'a> ImmutableSetTypes<'a, T, Output = &'a T>
{
    fn contains(&self, val: &Q) -> bool { self.inner.contains(val) }

    fn iter<'a>(&'a self) -> <Self as ImmutableSetTypes<'a, T>>::Iter{ 
        self.inner.iter().cloned() 
    }
}

impl<T, Q: ?Sized, C> GrowableSet<T, Q> for ByValue<C>
where 
    T: Borrow<Q> + Copy + 'static, 
    C: GrowableSet<T, Q> + for<'a> ImmutableSetTypes<'a, T, Output = &'a T>
{
    fn insert(&mut self, val: T) -> bool { self.inner.insert(val) }
    fn remove(&mut self, val: &Q) -> bool { self.inner.remove(val) }
}

// ++++++++++++++++++++ QCollect/Map-traits ++++++++++++++++++++

// TODO
/*
impl<'a, K, V, C> ImmutableMapTypes<'a, K, V> for ByValue<C>
    where V: Copy + 'static, C: ImmutableMapTypes<'a, T, OutputVal = &'a V>
{
    type OutputKey = C::OutputKey;
    type OutputVal = T;
    type Iter = iter::Cloned<C::Iter>; <--- need a new iterator type here
} 
*/

// ++++++++++++++++++++ Iteration-stuff ++++++++++++++++++++

use std::iter::FromIterator;

impl<A, C> FromIterator<A> for ByValue<C>
    where C: FromIterator<A> + GrowableCollection
{
    fn from_iter<I>(iterable: I) -> Self
        where I: IntoIterator<Item = A>
    {
        Self::new(C::from_iter(iterable))
    }
}

impl<A, C> Extend<A> for ByValue<C>
    where C: Extend<A> + GrowableCollection 
{
    fn extend<I>(&mut self, iterable: I)
        where I: IntoIterator<Item = A>
    { self.inner.extend(iterable); }
}

// TODO
//impl<'a, C> IntoIterator for &'a ByValue<C>
//impl<'a, C> IntoIterator for &'a mut ByValue<C>

impl<C> IntoIterator for ByValue<C>
    where C: IntoIterator + ImmutableCollection
{
    type Item = C::Item;
    type IntoIter = C::IntoIter;
    fn into_iter(self) -> Self::IntoIter { self.inner.into_iter() }
}


// ++++++++++++++++++++ StdPrelude ++++++++++++++++++++

impl<C> Default for ByValue<C>
    where C: Default + ImmutableCollection
{
    fn default() -> Self { Self::new(C::default()) }
}