<commit_before>//! Collection traits for generic programming.

#![deny(missing_docs)]
#![feature(linked_list_extras)]
#![feature(set_recovery)]

mod std_impls;

pub use collection::Collection;
pub use list::List;
pub use map::Map;
pub use seq::{Deque, Queue, Stack};
pub use set::Set;

pub mod collection {
    //! Collections.

    /// A collection.
    pub trait Collection {
        /// The type of the collection's items.
        type Item;

        /// Checks if the collection contains zero items.
        ///
        /// This is equivalent to `self.len() == 0`, but may be optimized.
        fn is_empty(&self) -> bool {
            self.len() == 0
        }

        /// Returns the number of items in the collection.
        fn len(&self) -> usize;
    }

    /// A collection that supports insertion.
    pub trait Insert: Collection {
        /// Moves all items from the given collection into the collection.
        fn append(&mut self, other: &mut Self) where Self: Sized;
    }

    /// A collection that supports removal.
    pub trait Remove: Collection {
        /// Removes all items from the collection.
        fn clear(&mut self);
    }

    #[test]
    fn test_object_safety() {
        let _: &Collection<Item = i32>;
        let _: &Remove<Item = i32>;
        let _: &Insert<Item = i32>;
    }
}

pub mod list {
    //! Lists.

    use super::*;

    /// A list.
    pub trait List: Collection {
        /// Returns a reference to the item at the given index.
        ///
        /// Returns `None` if `index >= self.len()`.
        fn get(&self, index: usize) -> Option<&Self::Item>;

        /// Returns a mutable reference to the item at the given index.
        ///
        /// Returns `None` if `index >= self.len()`.
        fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>;

        /// Swaps the items at the given indices in the list.
        ///
        /// # Panics
        ///
        /// Panics if `i >= self.len() || j >= self.len()`.
        fn swap(&mut self, i: usize, j: usize);
    }

    /// A list that supports insertion.
    pub trait Insert: List {
        /// Inserts the given item into the list at the given index.
        ///
        /// All items after the given index are shifted one index to the right.
        ///
        /// # Panics
        ///
        /// Panics if `index > self.len()`.
        fn insert(&mut self, index: usize, item: Self::Item);

        /// Pushes the given item onto the back of the list.
        fn push(&mut self, item: Self::Item) {
            let len = self.len();
            self.insert(len, item);
        }
    }

    /// A list that supports removal.
    pub trait Remove: List {
        /// Removes the last item in the list.
        ///
        /// Returns `None` if the list is empty.
        fn pop(&mut self) -> Option<Self::Item> {
            if self.is_empty() {
                None
            } else {
                let len = self.len();
                self.remove(len - 1)
            }
        }

        /// Removes the item at the given index from the list and returns it.
        ///
        /// Returns `None` if `index >= self.len()`.
        fn remove(&mut self, index: usize) -> Option<Self::Item>;

        /// Splits the list in two at the given index.
        ///
        /// After this method returns, `self` contains the items `[0, index)` and the returned list
        /// contains the items `[index, len)`.
        ///
        /// # Panics
        ///
        /// Panics if `index > self.len()`.
        fn split_off(&mut self, index: usize) -> Self where Self: Sized;

        /// Removes the item at the given index from the list and returns it, replacing it with the
        /// last item in the list.
        ///
        /// Returns `None` if `index >= self.len()`.
        fn swap_remove(&mut self, index: usize) -> Option<Self::Item> {
            if index >= self.len() {
                None
            } else {
                let len = self.len();
                self.swap(index, len - 1);
                self.pop()
            }
        }
    }

    #[test]
    fn test_object_safety() {
        let _: &List<Item = i32>;
        let _: &Insert<Item = i32>;
        let _: &Remove<Item = i32>;
    }
}

pub mod map {
    //! Maps.

    use super::*;

    /// A map.
    ///
    /// A map is a collection that associates keys with values, where the keys are distinguished
    /// according to some uniqueness criteria.
    pub trait Map: Collection<Item = (<Self as Map>::Key, <Self as Map>::Value)> {
        /// The type of the map's keys.
        type Key;

        /// The type of the map's values.
        type Value;

        /// Returns the entry in the map corresponding to the given key.
        fn entry<'a>(&'a mut self, key: Self::Key) -> Entry<'a, Self::Key, Self::Value>
            where Self: Insert + Remove;
    }

    /// A map that supports lookups using keys of type `&Q`.
    pub trait Get<Q: ?Sized = <Self as Map>::Key>: Map {
        /// Checks if the map contains a key that is equivalent to the given key.
        ///
        /// This is equivalent to `self.get(key).is_some()`, but may be optimized.
        fn contains_key(&self, key: &Q) -> bool {
            self.get(key).is_some()
        }

        /// Returns a reference to the value in the map whose key is equivalent to the given key.
        ///
        /// Returns `None` if the map contains no such key.
        fn get(&self, key: &Q) -> Option<&Self::Value>;

        /// Returns a mutable reference to the value in the map whose key is equivalent to the
        /// given key.
        ///
        /// Returns `None` if the map contains no such key.
        fn get_mut(&mut self, key: &Q) -> Option<&mut Self::Value>;
    }

    /// A map that supports removals using keys of type `&Q`.
    pub trait Remove<Q: ?Sized = <Self as Map>::Key>: Get<Q> + collection::Remove {
        /// Removes the key in the map that is equivalent to the given key and returns its value.
        ///
        /// Returns `None` if the map contains no such key.
        fn remove(&mut self, key: &Q) -> Option<Self::Value>;
    }

    /// A map that supports insertion.
    pub trait Insert: Map + collection::Insert {
        /// Inserts the given key and value into the map and returns the previous value
        /// corresponding to the given key, if any.
        fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
    }

    /// An occupied map entry.
    ///
    /// `'a` is the lifetime of the map.
    pub trait OccupiedEntry {
        /// The type of the entry's key.
        type Key;

        /// The type of the entry's value.
        type Value;

        /// The return type of `into_mut`.
        type MutValue;

        /// Returns a reference to the entry's value.
        fn get(&self) -> &Self::Value;

        /// Returns a mutable reference to the entry's value.
        fn get_mut(&mut self) -> &mut Self::Value;

        /// Returns a mutable reference to the entry's value with the same lifetime as the map.
        fn into_mut(self: Box<Self>) -> Self::MutValue;

        /// Replaces the entry's value with the given one and returns the old value.
        fn insert(&mut self, value: Self::Value) -> Self::Value {
            ::std::mem::replace(self.get_mut(), value)
        }

        /// Removes the entry from the map and returns its value.
        fn remove(self: Box<Self>) -> Self::Value;
    }

    /// A vacant map entry.
    ///
    /// `'a` is the lifetime of the map.
    pub trait VacantEntry {
        /// The type of the entry's key.
        type Key;

        /// The type of the entry's value.
        type Value;

        /// The return type of `insert`.
        type MutValue;

        /// Inserts the entry into the map with the given value and returns a mutable reference to
        /// it with the same lifetime as the map.
        fn insert(self: Box<Self>, value: Self::Value) -> Self::MutValue;
    }

    /// A map entry.
    pub enum Entry<'a, K: 'a, V: 'a> {
        /// An occupied map entry.
        Occupied(Box<OccupiedEntry<Key = K, Value = V, MutValue = &'a mut V> + 'a>),
        /// A vacant map entry.
        Vacant(Box<VacantEntry<Key = K, Value = V, MutValue = &'a mut V> + 'a>),
    }

    impl<'a, K: 'a, V: 'a> Entry<'a, K, V> {
        /// Ensures the entry is occupied by inserting it with the given default value if it is
        /// vacant.
        pub fn or_insert(self, default: V) -> &'a mut V {
            match self {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(default),
            }
        }

        /// Ensures the entry is occupied by inserting it with the result of the given function if
        /// it is vacant.
        pub fn or_insert_with<F: FnOnce() -> V>(self, f: F) -> &'a mut V {
            match self {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(f()),
            }
        }
    }

    #[cfg(test)]
    pub fn count<M, I>(items: I) -> M
    where
        M: Default + map::Insert<Value = usize> + map::Remove,
        I: IntoIterator<Item = M::Key>,
    {
        let mut map = M::default();
        for item in items { *map.entry(item).or_insert(0) += 1; }
        map
    }

    #[test]
    fn test_object_safety() {
        let _: &Map<Item = (i32, char), Key = i32, Value = char>;
        let _: &Get<i32, Item = (i32, char), Key = i32, Value = char>;
        let _: &Remove<i32, Item = (i32, char), Key = i32, Value = char>;
        let _: &Insert<Item = (i32, char), Key = i32, Value = char>;
        let _: &OccupiedEntry<Key = i32, Value = char, MutValue = &mut char>;
        let _: &VacantEntry<Key = i32, Value = char, MutValue = &mut char>;
    }
}

pub mod seq {
    //! Sequences.

    use super::*;

    /// A sequence that supports insertion.
    pub trait PushBack: collection::Insert {
        /// Pushes the given item onto the back of the sequence.
        fn push_back(&mut self, item: Self::Item);
    }

    /// A queue.
    pub trait Queue: PushBack + collection::Remove {
        /// Returns a reference to the item at the front of the queue.
        ///
        /// Returns `None` if the queue is empty.
        fn front(&self) -> Option<&Self::Item>;

        /// Returns a mutable reference to the item at the front of the queue.
        ///
        /// Returns `None` if the queue is empty.
        fn front_mut(&mut self) -> Option<&mut Self::Item>;

        /// Removes and returns the item at the front of the queue.
        ///
        /// Returns `None` if the queue is empty.
        fn pop_front(&mut self) -> Option<Self::Item>;
    }

    /// A stack.
    pub trait Stack: PushBack + collection::Remove {
        /// Returns a reference to the item at the back of the stack.
        ///
        /// Returns `None` if the stack is empty.
        fn back(&self) -> Option<&Self::Item>;

        /// Returns a mutable reference to the item at the back of the stack.
        ///
        /// Returns `None` if the stack is empty.
        fn back_mut(&mut self) -> Option<&mut Self::Item>;

        /// Removes and returns the item at the back of the stack.
        ///
        /// Returns `None` if the stack is empty.
        fn pop_back(&mut self) -> Option<Self::Item>;
    }

    /// A deque (double-ended queue).
    pub trait Deque: Queue + Stack {
        /// Pushes the given item onto the front of the deque.
        fn push_front(&mut self, item: Self::Item);
    }

    #[test]
    fn test_object_safety() {
        let _: &PushBack<Item = i32>;
        let _: &Queue<Item = i32>;
        let _: &Stack<Item = i32>;
        let _: &Deque<Item = i32>;
    }
}

pub mod set {
    //! Sets.

    use super::*;

    /// A set.
    ///
    /// A set is a collection whose items are distinguished according to some uniqueness criteria.
    pub trait Set: Collection {
        /// Checks if the set is disjoint from the given set.
        fn is_disjoint(&self, other: &Self) -> bool where Self: Sized;

        /// Checks if the set is a subset of the given set.
        fn is_subset(&self, other: &Self) -> bool where Self: Sized;

        /// Checks if the set is a superset of the given set.
        fn is_superset(&self, other: &Self) -> bool where Self: Sized {
            other.is_subset(self)
        }
    }

    /// A set that supports retrievals using items of type `&Q`.
    pub trait Get<Q: ?Sized = <Self as Collection>::Item>: Set {
        /// Checks if the set contains an item that is equivalent to the given item.
        ///
        /// This is equivalent to `self.get(item).is_some()`, but may be optimized.
        fn contains(&self, item: &Q) -> bool {
            self.get(item).is_some()
        }

        /// Returns the item in the set that is equivalent to the given item.
        ///
        /// Returns `None` if the set contains no such item.
        fn get(&self, item: &Q) -> Option<&Self::Item>;
    }

    /// A set that supports removal using items of type `&Q`.
    pub trait Remove<Q: ?Sized = <Self as Collection>::Item>: Get<Q> + collection::Remove {
        /// Removes the item in the set that is equivalent to the given item.
        ///
        /// Returns `true` if the set contained such an item, `false` otherwise.
        ///
        /// This is equivalent to `self.take(item).is_some()`, but may be optimized.
        fn remove(&mut self, item: &Q) -> bool {
            self.take(item).is_some()
        }

        /// Removes and returns the item in the set that is equivalent to the given item.
        ///
        /// Returns `None` if the set contained no such item.
        fn take(&mut self, item: &Q) -> Option<Self::Item>;
    }

    /// A set that supports insertion.
    pub trait Insert: Set + collection::Insert {
        /// Inserts the given item into the set without replacement.
        ///
        /// Returns `true` if the set contained an equivalent item, `false` otherwise.
        fn insert(&mut self, item: Self::Item) -> bool;

        /// Inserts the given item into the set with replacement.
        ///
        /// Returns the equivalent item if the set contained one, `None` otherwise.
        fn replace(&mut self, item: Self::Item) -> Option<Self::Item>;
    }

    #[test]
    fn test_object_safety() {
        let _: &Set<Item = i32>;
        let _: &Get<i32, Item = i32>;
        let _: &Remove<i32, Item = i32>;
        let _: &Insert<Item = i32>;
    }
}
<commit_msg>Move object safety tests into dead method<commit_after>//! Collection traits for generic programming.

#![deny(missing_docs)]
#![feature(linked_list_extras)]
#![feature(set_recovery)]

mod std_impls;

pub use collection::Collection;
pub use list::List;
pub use map::Map;
pub use seq::{Deque, Queue, Stack};
pub use set::Set;

pub mod collection {
    //! Collections.

    /// A collection.
    pub trait Collection {
        /// The type of the collection's items.
        type Item;

        /// Checks if the collection contains zero items.
        ///
        /// This is equivalent to `self.len() == 0`, but may be optimized.
        fn is_empty(&self) -> bool {
            self.len() == 0
        }

        /// Returns the number of items in the collection.
        fn len(&self) -> usize;
    }

    /// A collection that supports insertion.
    pub trait Insert: Collection {
        /// Moves all items from the given collection into the collection.
        fn append(&mut self, other: &mut Self) where Self: Sized;
    }

    /// A collection that supports removal.
    pub trait Remove: Collection {
        /// Removes all items from the collection.
        fn clear(&mut self);
    }
}

pub mod list {
    //! Lists.

    use super::*;

    /// A list.
    pub trait List: Collection {
        /// Returns a reference to the item at the given index.
        ///
        /// Returns `None` if `index >= self.len()`.
        fn get(&self, index: usize) -> Option<&Self::Item>;

        /// Returns a mutable reference to the item at the given index.
        ///
        /// Returns `None` if `index >= self.len()`.
        fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>;

        /// Swaps the items at the given indices in the list.
        ///
        /// # Panics
        ///
        /// Panics if `i >= self.len() || j >= self.len()`.
        fn swap(&mut self, i: usize, j: usize);
    }

    /// A list that supports insertion.
    pub trait Insert: List {
        /// Inserts the given item into the list at the given index.
        ///
        /// All items after the given index are shifted one index to the right.
        ///
        /// # Panics
        ///
        /// Panics if `index > self.len()`.
        fn insert(&mut self, index: usize, item: Self::Item);

        /// Pushes the given item onto the back of the list.
        fn push(&mut self, item: Self::Item) {
            let len = self.len();
            self.insert(len, item);
        }
    }

    /// A list that supports removal.
    pub trait Remove: List {
        /// Removes the last item in the list.
        ///
        /// Returns `None` if the list is empty.
        fn pop(&mut self) -> Option<Self::Item> {
            if self.is_empty() {
                None
            } else {
                let len = self.len();
                self.remove(len - 1)
            }
        }

        /// Removes the item at the given index from the list and returns it.
        ///
        /// Returns `None` if `index >= self.len()`.
        fn remove(&mut self, index: usize) -> Option<Self::Item>;

        /// Splits the list in two at the given index.
        ///
        /// After this method returns, `self` contains the items `[0, index)` and the returned list
        /// contains the items `[index, len)`.
        ///
        /// # Panics
        ///
        /// Panics if `index > self.len()`.
        fn split_off(&mut self, index: usize) -> Self where Self: Sized;

        /// Removes the item at the given index from the list and returns it, replacing it with the
        /// last item in the list.
        ///
        /// Returns `None` if `index >= self.len()`.
        fn swap_remove(&mut self, index: usize) -> Option<Self::Item> {
            if index >= self.len() {
                None
            } else {
                let len = self.len();
                self.swap(index, len - 1);
                self.pop()
            }
        }
    }
}

pub mod map {
    //! Maps.

    use super::*;

    /// A map.
    ///
    /// A map is a collection that associates keys with values, where the keys are distinguished
    /// according to some uniqueness criteria.
    pub trait Map: Collection<Item = (<Self as Map>::Key, <Self as Map>::Value)> {
        /// The type of the map's keys.
        type Key;

        /// The type of the map's values.
        type Value;

        /// Returns the entry in the map corresponding to the given key.
        fn entry<'a>(&'a mut self, key: Self::Key) -> Entry<'a, Self::Key, Self::Value>
            where Self: Insert + Remove;
    }

    /// A map that supports lookups using keys of type `&Q`.
    pub trait Get<Q: ?Sized = <Self as Map>::Key>: Map {
        /// Checks if the map contains a key that is equivalent to the given key.
        ///
        /// This is equivalent to `self.get(key).is_some()`, but may be optimized.
        fn contains_key(&self, key: &Q) -> bool {
            self.get(key).is_some()
        }

        /// Returns a reference to the value in the map whose key is equivalent to the given key.
        ///
        /// Returns `None` if the map contains no such key.
        fn get(&self, key: &Q) -> Option<&Self::Value>;

        /// Returns a mutable reference to the value in the map whose key is equivalent to the
        /// given key.
        ///
        /// Returns `None` if the map contains no such key.
        fn get_mut(&mut self, key: &Q) -> Option<&mut Self::Value>;
    }

    /// A map that supports removals using keys of type `&Q`.
    pub trait Remove<Q: ?Sized = <Self as Map>::Key>: Get<Q> + collection::Remove {
        /// Removes the key in the map that is equivalent to the given key and returns its value.
        ///
        /// Returns `None` if the map contains no such key.
        fn remove(&mut self, key: &Q) -> Option<Self::Value>;
    }

    /// A map that supports insertion.
    pub trait Insert: Map + collection::Insert {
        /// Inserts the given key and value into the map and returns the previous value
        /// corresponding to the given key, if any.
        fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
    }

    /// An occupied map entry.
    ///
    /// `'a` is the lifetime of the map.
    pub trait OccupiedEntry {
        /// The type of the entry's key.
        type Key;

        /// The type of the entry's value.
        type Value;

        /// The return type of `into_mut`.
        type MutValue;

        /// Returns a reference to the entry's value.
        fn get(&self) -> &Self::Value;

        /// Returns a mutable reference to the entry's value.
        fn get_mut(&mut self) -> &mut Self::Value;

        /// Returns a mutable reference to the entry's value with the same lifetime as the map.
        fn into_mut(self: Box<Self>) -> Self::MutValue;

        /// Replaces the entry's value with the given one and returns the old value.
        fn insert(&mut self, value: Self::Value) -> Self::Value {
            ::std::mem::replace(self.get_mut(), value)
        }

        /// Removes the entry from the map and returns its value.
        fn remove(self: Box<Self>) -> Self::Value;
    }

    /// A vacant map entry.
    ///
    /// `'a` is the lifetime of the map.
    pub trait VacantEntry {
        /// The type of the entry's key.
        type Key;

        /// The type of the entry's value.
        type Value;

        /// The return type of `insert`.
        type MutValue;

        /// Inserts the entry into the map with the given value and returns a mutable reference to
        /// it with the same lifetime as the map.
        fn insert(self: Box<Self>, value: Self::Value) -> Self::MutValue;
    }

    /// A map entry.
    pub enum Entry<'a, K: 'a, V: 'a> {
        /// An occupied map entry.
        Occupied(Box<OccupiedEntry<Key = K, Value = V, MutValue = &'a mut V> + 'a>),
        /// A vacant map entry.
        Vacant(Box<VacantEntry<Key = K, Value = V, MutValue = &'a mut V> + 'a>),
    }

    impl<'a, K: 'a, V: 'a> Entry<'a, K, V> {
        /// Ensures the entry is occupied by inserting it with the given default value if it is
        /// vacant.
        pub fn or_insert(self, default: V) -> &'a mut V {
            match self {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(default),
            }
        }

        /// Ensures the entry is occupied by inserting it with the result of the given function if
        /// it is vacant.
        pub fn or_insert_with<F: FnOnce() -> V>(self, f: F) -> &'a mut V {
            match self {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(f()),
            }
        }
    }

    #[cfg(test)]
    pub fn count<M, I>(items: I) -> M
    where
        M: Default + map::Insert<Value = usize> + map::Remove,
        I: IntoIterator<Item = M::Key>,
    {
        let mut map = M::default();
        for item in items { *map.entry(item).or_insert(0) += 1; }
        map
    }
}

pub mod seq {
    //! Sequences.

    use super::*;

    /// A sequence that supports insertion.
    pub trait PushBack: collection::Insert {
        /// Pushes the given item onto the back of the sequence.
        fn push_back(&mut self, item: Self::Item);
    }

    /// A queue.
    pub trait Queue: PushBack + collection::Remove {
        /// Returns a reference to the item at the front of the queue.
        ///
        /// Returns `None` if the queue is empty.
        fn front(&self) -> Option<&Self::Item>;

        /// Returns a mutable reference to the item at the front of the queue.
        ///
        /// Returns `None` if the queue is empty.
        fn front_mut(&mut self) -> Option<&mut Self::Item>;

        /// Removes and returns the item at the front of the queue.
        ///
        /// Returns `None` if the queue is empty.
        fn pop_front(&mut self) -> Option<Self::Item>;
    }

    /// A stack.
    pub trait Stack: PushBack + collection::Remove {
        /// Returns a reference to the item at the back of the stack.
        ///
        /// Returns `None` if the stack is empty.
        fn back(&self) -> Option<&Self::Item>;

        /// Returns a mutable reference to the item at the back of the stack.
        ///
        /// Returns `None` if the stack is empty.
        fn back_mut(&mut self) -> Option<&mut Self::Item>;

        /// Removes and returns the item at the back of the stack.
        ///
        /// Returns `None` if the stack is empty.
        fn pop_back(&mut self) -> Option<Self::Item>;
    }

    /// A deque (double-ended queue).
    pub trait Deque: Queue + Stack {
        /// Pushes the given item onto the front of the deque.
        fn push_front(&mut self, item: Self::Item);
    }
}

pub mod set {
    //! Sets.

    use super::*;

    /// A set.
    ///
    /// A set is a collection whose items are distinguished according to some uniqueness criteria.
    pub trait Set: Collection {
        /// Checks if the set is disjoint from the given set.
        fn is_disjoint(&self, other: &Self) -> bool where Self: Sized;

        /// Checks if the set is a subset of the given set.
        fn is_subset(&self, other: &Self) -> bool where Self: Sized;

        /// Checks if the set is a superset of the given set.
        fn is_superset(&self, other: &Self) -> bool where Self: Sized {
            other.is_subset(self)
        }
    }

    /// A set that supports retrievals using items of type `&Q`.
    pub trait Get<Q: ?Sized = <Self as Collection>::Item>: Set {
        /// Checks if the set contains an item that is equivalent to the given item.
        ///
        /// This is equivalent to `self.get(item).is_some()`, but may be optimized.
        fn contains(&self, item: &Q) -> bool {
            self.get(item).is_some()
        }

        /// Returns the item in the set that is equivalent to the given item.
        ///
        /// Returns `None` if the set contains no such item.
        fn get(&self, item: &Q) -> Option<&Self::Item>;
    }

    /// A set that supports removal using items of type `&Q`.
    pub trait Remove<Q: ?Sized = <Self as Collection>::Item>: Get<Q> + collection::Remove {
        /// Removes the item in the set that is equivalent to the given item.
        ///
        /// Returns `true` if the set contained such an item, `false` otherwise.
        ///
        /// This is equivalent to `self.take(item).is_some()`, but may be optimized.
        fn remove(&mut self, item: &Q) -> bool {
            self.take(item).is_some()
        }

        /// Removes and returns the item in the set that is equivalent to the given item.
        ///
        /// Returns `None` if the set contained no such item.
        fn take(&mut self, item: &Q) -> Option<Self::Item>;
    }

    /// A set that supports insertion.
    pub trait Insert: Set + collection::Insert {
        /// Inserts the given item into the set without replacement.
        ///
        /// Returns `true` if the set contained an equivalent item, `false` otherwise.
        fn insert(&mut self, item: Self::Item) -> bool;

        /// Inserts the given item into the set with replacement.
        ///
        /// Returns the equivalent item if the set contained one, `None` otherwise.
        fn replace(&mut self, item: Self::Item) -> Option<Self::Item>;
    }
}

#[allow(dead_code)]
fn assert_object_safe() {
    let _: Collection<Item = String>;
    let _: collection::Insert<Item = String>;
    let _: collection::Remove<Item = String>;

    let _: &List<Item = String>;
    let _: &list::Insert<Item = String>;
    let _: &list::Remove<Item = String>;

    let _: &Map<Item = (String, i32), Key = String, Value = i32>;
    let _: &map::Insert<Item = (String, i32), Key = String, Value = i32>;
    let _: &map::Get<str, Item = (String, i32), Key = String, Value = i32>;
    let _: &map::Remove<str, Item = (String, i32), Key = String, Value = i32>;
    let _: &map::OccupiedEntry<Key = String, Value = i32, MutValue = &mut i32>;
    let _: &map::VacantEntry<Key = String, Value = i32, MutValue = &mut i32>;

    let _: &seq::PushBack<Item = String>;
    let _: &Queue<Item = String>;
    let _: &Stack<Item = String>;
    let _: &Deque<Item = String>;

    let _: &Set<Item = String>;
    let _: &set::Insert<Item = String>;
    let _: &set::Get<str, Item = String>;
    let _: &set::Remove<str, Item = String>;
}
<|endoftext|>


<commit_before>// #![feature(std_misc)]

use std::default::Default;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

// use std::collections::HashMap;
// use std::hash::Hash;

/// A value that has some default type that can recycle it.
pub trait Recyclable {
    type DefaultRecycler: Recycler<Item=Self>;
}

pub fn make_recycler<T: Recyclable>() -> T::DefaultRecycler {
    Default::default()
}

// These really want default associated types. (rust-lang/rust#19476)
impl Recyclable for u8 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for i8 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for u16 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for i16 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for u32 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for i32 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for u64 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for i64 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for usize { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for isize { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for () { type DefaultRecycler = TrashRecycler<Self>; }

impl Recyclable for String {
    type DefaultRecycler = StringRecycler;
}

impl<T: Recyclable> Recyclable for Vec<T> {
    type DefaultRecycler = VecRecycler<T::DefaultRecycler>;
}

impl<T: Recyclable> Recyclable for Option<T> {
    type DefaultRecycler = OptionRecycler<T::DefaultRecycler>;
}

impl<A: Recyclable, B: Recyclable> Recyclable for (A, B) {
    type DefaultRecycler = (A::DefaultRecycler, B::DefaultRecycler);
}

// allows recycling of items
pub trait Recycler : Default {
    type Item;
    fn recycle(&mut self, _item: Self::Item) { }
}

/// A "recycler" that doesn't recycle anything, instead just dropping anything
/// it is given. This is particularly useful for primitive types such as `i32`
/// that do not have `Drop` implementations.
pub struct TrashRecycler<Item> {
    marker: PhantomData<Item>
}

impl<Item> Default for TrashRecycler<Item> {
    fn default() -> Self {
        TrashRecycler {
            marker: PhantomData
        }
    }
}

impl<Item> Recycler for TrashRecycler<Item> {
    type Item = Item;
}

// demonstrating how tuples might be recycled
impl<R1: Recycler, R2: Recycler> Recycler for (R1, R2) {
    type Item = (R1::Item, R2::Item);
    fn recycle(&mut self, (part1, part2): (R1::Item, R2::Item)) {
        self.0.recycle(part1);
        self.1.recycle(part2);
    }
}

#[derive(Default)]
pub struct StringRecycler {
    stash: Vec<String>
}

impl Recycler for StringRecycler {
    type Item = String;
    fn recycle(&mut self, mut string: String) {
        string.clear();
        self.stash.push(string);
    }
}

impl StringRecycler {
    pub fn new(&mut self) -> String {
        self.stash.pop().unwrap_or(String::new())
    }
    pub fn new_from(&mut self, s: &str) -> String {
        let mut string = self.new();
        string.push_str(s);
        string
    }
}

// A recycler for vectors and their contents
pub struct VecRecycler<R: Recycler> {
    pub recycler: R,
    stash: Vec<Vec<R::Item>>,
}

// recycles vec contents, then stashes the vec
impl<R: Recycler> Recycler for VecRecycler<R> {
    type Item = Vec<R::Item>;
    fn recycle(&mut self, mut vec: Vec<R::Item>) {
        while let Some(x) = vec.pop() {
            self.recycler.recycle(x)
        }
        self.stash.push(vec);
    }
}

impl<R: Recycler> VecRecycler<R> {
    pub fn new(&mut self) -> (Vec<R::Item>, &mut R) {
        (self.stash.pop().unwrap_or(Vec::new()), &mut self.recycler)
    }
}

impl<R: Recycler> Default for VecRecycler<R> {
    fn default() -> Self {
        VecRecycler {
            recycler: Default::default(),
            stash: Vec::new(),
        }
    }
}

// option recycler
#[derive(Default)]
pub struct OptionRecycler<R: Recycler> {
    pub recycler: R,
}

impl<R: Recycler> Recycler for OptionRecycler<R> {
    type Item = Option<R::Item>;
    fn recycle(&mut self, option: Option<R::Item>) {
        if let Some(thing) = option {
            self.recycler.recycle(thing);
        }
    }
}

// derefs to contained recycler
impl<R: Recycler> Deref for OptionRecycler<R> {
    type Target = R;
    fn deref(&self) -> &Self::Target { &self.recycler }
}

// derefs to contained recycler, permits .new()
impl<R: Recycler> DerefMut for OptionRecycler<R> {
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.recycler }
}

// // commented out due to beta-instability of .drain()
// // recycles keys and values, then stashed the hashmap
// pub struct HashMapRecycler<KR: Recycler, VR: Recycler> {
//     pub key_recycler: KR,
//     pub val_recycler: VR,
//     pub stash: Vec<HashMap<KR::Item, VR::Item>>,
// }
//
// impl<KR: Recycler, VR: Recycler> Recycler for HashMapRecycler<KR, VR> where KR::Item: Eq+Hash {
//     type Item = HashMap<KR::Item, VR::Item>;
//     fn recycle(&mut self, mut map: HashMap<KR::Item, VR::Item>) {
//         for (key, val) in map.drain() {
//             self.key_recycler.recycle(key);
//             self.val_recycler.recycle(val);
//         }
//         self.stash.push(map);
//     }
// }
//
// impl<KR: Recycler, VR: Recycler> HashMapRecycler<KR, VR> where KR::Item: Eq+Hash {
//     pub fn new(&mut self) -> (HashMap<KR::Item, VR::Item>, (&mut KR, &mut VR)) {
//         (self.stash.pop().unwrap_or(HashMap::new()), (&mut self.key_recycler, &mut self.val_recycler))
//     }
// }
//
// impl<KR: Recycler, VR: Recycler> Default for HashMapRecycler<KR, VR> {
//     fn default() -> Self {
//         HashMapRecycler {
//             key_recycler: Default::default(),
//             val_recycler: Default::default(),
//             stash: Vec::new(),
//         }
//     }
// }
<commit_msg>added bool, commented hashmap recyclable impls<commit_after>// #![feature(std_misc)]

use std::default::Default;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

// use std::collections::HashMap;
// use std::hash::Hash;

/// A value that has some default type that can recycle it.
pub trait Recyclable {
    type DefaultRecycler: Recycler<Item=Self>;
}

pub fn make_recycler<T: Recyclable>() -> T::DefaultRecycler {
    Default::default()
}

// These really want default associated types. (rust-lang/rust#19476)
impl Recyclable for u8 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for i8 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for u16 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for i16 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for u32 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for i32 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for u64 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for i64 { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for usize { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for isize { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for bool { type DefaultRecycler = TrashRecycler<Self>; }
impl Recyclable for () { type DefaultRecycler = TrashRecycler<Self>; }

impl Recyclable for String {
    type DefaultRecycler = StringRecycler;
}

impl<T: Recyclable> Recyclable for Vec<T> {
    type DefaultRecycler = VecRecycler<T::DefaultRecycler>;
}

impl<T: Recyclable> Recyclable for Option<T> {
    type DefaultRecycler = OptionRecycler<T::DefaultRecycler>;
}

impl<A: Recyclable, B: Recyclable> Recyclable for (A, B) {
    type DefaultRecycler = (A::DefaultRecycler, B::DefaultRecycler);
}

// impl<K: Recyclable+Eq+Hash, V: Recyclable> Recyclable for HashMap<K, V> {
//     type DefaultRecycler = HashMapRecycler<K::DefaultRecycler, V::DefaultRecycler>;
// }

// allows recycling of items
pub trait Recycler : Default {
    type Item;
    fn recycle(&mut self, _item: Self::Item) { }
}

/// A "recycler" that doesn't recycle anything, instead just dropping anything
/// it is given. This is particularly useful for primitive types such as `i32`
/// that do not have `Drop` implementations.
pub struct TrashRecycler<Item> {
    marker: PhantomData<Item>
}

impl<Item> Default for TrashRecycler<Item> {
    fn default() -> Self {
        TrashRecycler {
            marker: PhantomData
        }
    }
}

impl<Item> Recycler for TrashRecycler<Item> {
    type Item = Item;
}

// demonstrating how tuples might be recycled
impl<R1: Recycler, R2: Recycler> Recycler for (R1, R2) {
    type Item = (R1::Item, R2::Item);
    fn recycle(&mut self, (part1, part2): (R1::Item, R2::Item)) {
        self.0.recycle(part1);
        self.1.recycle(part2);
    }
}

#[derive(Default)]
pub struct StringRecycler {
    stash: Vec<String>
}

impl Recycler for StringRecycler {
    type Item = String;
    fn recycle(&mut self, mut string: String) {
        string.clear();
        self.stash.push(string);
    }
}

impl StringRecycler {
    pub fn new(&mut self) -> String {
        self.stash.pop().unwrap_or(String::new())
    }
    pub fn new_from(&mut self, s: &str) -> String {
        let mut string = self.new();
        string.push_str(s);
        string
    }
}

// A recycler for vectors and their contents
pub struct VecRecycler<R: Recycler> {
    pub recycler: R,
    stash: Vec<Vec<R::Item>>,
}

// recycles vec contents, then stashes the vec
impl<R: Recycler> Recycler for VecRecycler<R> {
    type Item = Vec<R::Item>;
    fn recycle(&mut self, mut vec: Vec<R::Item>) {
        while let Some(x) = vec.pop() {
            self.recycler.recycle(x)
        }
        self.stash.push(vec);
    }
}

impl<R: Recycler> VecRecycler<R> {
    pub fn new(&mut self) -> (Vec<R::Item>, &mut R) {
        (self.stash.pop().unwrap_or(Vec::new()), &mut self.recycler)
    }
}

impl<R: Recycler> Default for VecRecycler<R> {
    fn default() -> Self {
        VecRecycler {
            recycler: Default::default(),
            stash: Vec::new(),
        }
    }
}

// option recycler
#[derive(Default)]
pub struct OptionRecycler<R: Recycler> {
    pub recycler: R,
}

impl<R: Recycler> Recycler for OptionRecycler<R> {
    type Item = Option<R::Item>;
    fn recycle(&mut self, option: Option<R::Item>) {
        if let Some(thing) = option {
            self.recycler.recycle(thing);
        }
    }
}

// derefs to contained recycler
impl<R: Recycler> Deref for OptionRecycler<R> {
    type Target = R;
    fn deref(&self) -> &Self::Target { &self.recycler }
}

// derefs to contained recycler, permits .new()
impl<R: Recycler> DerefMut for OptionRecycler<R> {
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.recycler }
}

// // commented out due to beta-instability of .drain()
// // recycles keys and values, then stashes the hashmap
// pub struct HashMapRecycler<KR: Recycler, VR: Recycler> {
//     pub key_recycler: KR,
//     pub val_recycler: VR,
//     pub stash: Vec<HashMap<KR::Item, VR::Item>>,
// }
//
// impl<KR: Recycler, VR: Recycler> Recycler for HashMapRecycler<KR, VR> where KR::Item: Eq+Hash {
//     type Item = HashMap<KR::Item, VR::Item>;
//     fn recycle(&mut self, mut map: HashMap<KR::Item, VR::Item>) {
//         for (key, val) in map.drain() {
//             self.key_recycler.recycle(key);
//             self.val_recycler.recycle(val);
//         }
//         self.stash.push(map);
//     }
// }
//
// impl<KR: Recycler, VR: Recycler> HashMapRecycler<KR, VR> where KR::Item: Eq+Hash {
//     pub fn new(&mut self) -> (HashMap<KR::Item, VR::Item>, (&mut KR, &mut VR)) {
//         (self.stash.pop().unwrap_or(HashMap::new()), (&mut self.key_recycler, &mut self.val_recycler))
//     }
// }
//
// impl<KR: Recycler, VR: Recycler> Default for HashMapRecycler<KR, VR> {
//     fn default() -> Self {
//         HashMapRecycler {
//             key_recycler: Default::default(),
//             val_recycler: Default::default(),
//             stash: Vec::new(),
//         }
//     }
// }
<|endoftext|>


<commit_before>use core::io;
use core::io::ReaderUtil;
use mul_reader;
use byte_helpers;

pub type Map = ~[Block];

pub type Block = ~[Cell];

pub struct Cell {
    graphic: u16,
    altitude: i8,
}

pub type Statics = ~[StaticLocation];

pub struct StaticLocation {
    object_id: u16,
    x: u8,
    y: u8,
    altitude: i8,
    remainder: u16
}

const BLOCK_SIZE: uint = 196;
const OFFSET: uint = 4;

pub struct MapReader {
    data_reader: io::Reader
}

impl MapReader {

    /**
     * Read a specific block from a map
     */
    fn read_block(&self, id: uint) -> Block {
        //Cycle to id * 196 + Offset
        self.data_reader.seek(((id * BLOCK_SIZE) + OFFSET) as int, io::SeekSet);
        let map_reader = self.data_reader;
        //Read the 64 cells
        let mut block: Block = ~[];
        //Read 64 cells
        for uint::range(0, 64) |_index| {
            block.push(Cell{
                graphic: map_reader.read_le_u16(),
                altitude: map_reader.read_i8()
            });
        }
        block
    }

    /**
     * Read the whole map!
     */
    fn read_map(&self, max_blocks: uint) -> Map {
        let mut map: Map = ~[];
        let mut index = 0;
        while index < max_blocks {
            map.push(self.read_block(index));
            index += 1;
        }
        map
    }
}

/**
 * Create a handle to a mapreader, and read out given blocks as needed
 */
pub fn MapReader(mul_path: &path::Path) -> result::Result<MapReader, ~str> {
    match io::file_reader(mul_path) {
        result::Ok(data_reader) => {
            result::Ok(MapReader {
                data_reader: data_reader
            })
        },
        result::Err(error_message) => {
            result::Err(error_message)
        }
    }
}

pub struct StaticReader {
    mul_reader: mul_reader::MulReader
}

impl StaticReader {
    pub fn read_block(&self, id: uint) -> option::Option<Statics> {
        match self.mul_reader.read(id) {
            option::Some(record) => {
                assert record.data.len() % 7 == 0;
                let mut statics:Statics = ~[];
                let mut data_source = byte_helpers::Buffer(copy record.data);
                for uint::range_step(0, record.data.len(), 7) |_i| {
                    let object_id: u16 = byte_helpers::bytes_to_le_uint(data_source.read_items(2)) as u16;
                    let x: u8 = byte_helpers::bytes_to_le_uint(data_source.read_items(1)) as u8;
                    let y: u8 = byte_helpers::bytes_to_le_uint(data_source.read_items(1)) as u8;
                    let altitude: i8 = byte_helpers::bytes_to_le_uint(data_source.read_items(1)) as i8;
                    let remainder: u16 = byte_helpers::bytes_to_le_uint(data_source.read_items(2)) as u16;
                    statics.push(StaticLocation{
                        object_id: object_id,
                        x: x,
                        y: y,
                        altitude: altitude,
                        remainder: remainder
                    });
                }
                option::Some(statics)
            }
            option::None => {
                option::None
            }
        }
    }
}

pub fn StaticReader(index_path: &path::Path, mul_path: &path::Path) -> result::Result<StaticReader, ~str> {
    match mul_reader::MulReader(index_path, mul_path) {
        result::Err(message) => result::Err(message),
        result::Ok(mul_reader) => {
            result::Ok(StaticReader{
                mul_reader: mul_reader
            })
        }
    }
}
<commit_msg>Made some needed methods public<commit_after>use core::io;
use core::io::ReaderUtil;
use mul_reader;
use byte_helpers;

pub type Map = ~[Block];

pub type Block = ~[Cell];

pub struct Cell {
    graphic: u16,
    altitude: i8,
}

pub type Statics = ~[StaticLocation];

pub struct StaticLocation {
    object_id: u16,
    x: u8,
    y: u8,
    altitude: i8,
    remainder: u16
}

const BLOCK_SIZE: uint = 196;
const OFFSET: uint = 4;

pub struct MapReader {
    data_reader: io::Reader
}

impl MapReader {

    /**
     * Read a specific block from a map
     */
    pub fn read_block(&self, id: uint) -> Block {
        //Cycle to id * 196 + Offset
        self.data_reader.seek(((id * BLOCK_SIZE) + OFFSET) as int, io::SeekSet);
        let map_reader = self.data_reader;
        //Read the 64 cells
        let mut block: Block = ~[];
        //Read 64 cells
        for uint::range(0, 64) |_index| {
            block.push(Cell{
                graphic: map_reader.read_le_u16(),
                altitude: map_reader.read_i8()
            });
        }
        block
    }

    /**
     * Read the whole map!
     */
    pub fn read_map(&self, max_blocks: uint) -> Map {
        let mut map: Map = ~[];
        let mut index = 0;
        while index < max_blocks {
            map.push(self.read_block(index));
            index += 1;
        }
        map
    }
}

/**
 * Create a handle to a mapreader, and read out given blocks as needed
 */
pub fn MapReader(mul_path: &path::Path) -> result::Result<MapReader, ~str> {
    match io::file_reader(mul_path) {
        result::Ok(data_reader) => {
            result::Ok(MapReader {
                data_reader: data_reader
            })
        },
        result::Err(error_message) => {
            result::Err(error_message)
        }
    }
}

pub struct StaticReader {
    mul_reader: mul_reader::MulReader
}

impl StaticReader {
    pub fn read_block(&self, id: uint) -> option::Option<Statics> {
        match self.mul_reader.read(id) {
            option::Some(record) => {
                assert record.data.len() % 7 == 0;
                let mut statics:Statics = ~[];
                let mut data_source = byte_helpers::Buffer(copy record.data);
                for uint::range_step(0, record.data.len(), 7) |_i| {
                    let object_id: u16 = byte_helpers::bytes_to_le_uint(data_source.read_items(2)) as u16;
                    let x: u8 = byte_helpers::bytes_to_le_uint(data_source.read_items(1)) as u8;
                    let y: u8 = byte_helpers::bytes_to_le_uint(data_source.read_items(1)) as u8;
                    let altitude: i8 = byte_helpers::bytes_to_le_uint(data_source.read_items(1)) as i8;
                    let remainder: u16 = byte_helpers::bytes_to_le_uint(data_source.read_items(2)) as u16;
                    statics.push(StaticLocation{
                        object_id: object_id,
                        x: x,
                        y: y,
                        altitude: altitude,
                        remainder: remainder
                    });
                }
                option::Some(statics)
            }
            option::None => {
                option::None
            }
        }
    }
}

pub fn StaticReader(index_path: &path::Path, mul_path: &path::Path) -> result::Result<StaticReader, ~str> {
    match mul_reader::MulReader(index_path, mul_path) {
        result::Err(message) => result::Err(message),
        result::Ok(mul_reader) => {
            result::Ok(StaticReader{
                mul_reader: mul_reader
            })
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![macro_escape]

use std::fmt;
use std::mem;
use std::num::NumCast;
use std::ops::Index;
use std::raw::Slice;
use std::slice::AsSlice;
use blas::default::Default;
use blas::matrix::Matrix;
use blas::matrix::ops::{
    Gemm,
};
use blas::matrix_vector::ops::{
    Gemv,
};
use blas::vector::ops::Copy;

pub struct Mat<T> {
    rows: uint,
    cols: uint,
    data: Vec<T>,
}

impl<T> Mat<T> {
    #[inline]
    pub fn new() -> Mat<T> {
        let _data: Vec<T> = Vec::new();
        Mat { rows: 0, cols: 0, data: _data }
    }

    #[inline]
    pub fn from_vec(rows: uint, cols: uint, vec: Vec<T>) -> Mat<T> {
        Mat { rows: rows, cols: cols, data: vec }
    }

    #[inline]
    pub fn zero(rows: uint, cols: uint) -> Mat<T> {
        let mut _data: Vec<T> = Vec::with_capacity(rows * cols);
        unsafe { _data.set_len(rows * cols); }
        Mat { rows: rows, cols: cols, data: _data}
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        self.data.push(value);
    }

    #[inline]
    pub fn rows(&self) -> uint {
        self.rows
    }

    #[inline]
    pub fn cols(&self) -> uint {
        self.cols
    }

    #[inline]
    pub unsafe fn set_rows(&mut self, rows: uint) {
        self.rows = rows;
    }

    #[inline]
    pub unsafe fn set_cols(&mut self, cols: uint) {
        self.cols = cols;
    }

    #[inline]
    pub unsafe fn as_slice<'a>(&'a self) -> &'a [T] {
        self.data.as_slice()
    }

    #[inline]
    pub unsafe fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.data.as_mut_slice()
    }
}

impl<T> Matrix<T> for Mat<T> {
    #[inline]
    fn rows(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.rows());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn cols(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.cols());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T {
        unsafe { self.as_slice().as_ptr() }
    }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T {
        unsafe { self.as_mut_slice().as_mut_ptr() }
    }
}

impl<T: Copy> Clone for Mat<T> {
    fn clone(&self) -> Mat<T> {
        let n = self.rows * self.cols;

        let mut x = Vec::with_capacity(n);
        unsafe {
            Copy::copy(&self.data, &mut x);
            x.set_len(n);
        }

        Mat::from_vec(self.rows, self.cols, x)
    }
}

impl<T: PartialEq> PartialEq for Mat<T> {
    fn eq(&self, other: &Mat<T>) -> bool {
        self.rows == other.rows &&
        self.cols == other.cols &&
        self.data == other.data
    }
}

impl<T> Index<uint, [T]> for Mat<T> {
    fn index<'a>(&'a self, index: &uint) -> &'a [T] {
        unsafe {
            let ptr = self.data.as_slice().as_ptr().offset((*index * self.cols) as int);
            mem::transmute(Slice { data: ptr, len: self.cols })
        }
    }
}

impl<T: fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in range(0u, self.rows) {
            match writeln!(f, "{}", &self[i]) {
                Ok(_) => (),
                x => return x,
            }
        }

        Ok(())
    }
}

impl<'a, T> Mul<&'a Vec<T>, Vec<T>> for Mat<T>
where T: Default + Gemv {
    fn mul(&self, x: &'a Vec<T>) -> Vec<T> {
        let mut result = Vec::with_capacity(self.rows);

        Gemv::gemv(&Default::one(), self, x, &Default::zero(), &mut result);
        unsafe { result.set_len(self.rows); }

        result
    }
}

impl<'a, T> Mul<&'a Mat<T>, Mat<T>> for Mat<T>
where T: Default + Gemm {
    fn mul(&self, b: &'a Mat<T>) -> Mat<T> {
        let mut result = Mat::zero(self.cols, b.rows);
        Gemm::gemm(&Default::one(), self, b, &Default::zero(), &mut result);

        result
    }
}

#[macro_export]
macro_rules! mat(
    ($($($e: expr),+);*) => ({
        // leading _ to allow empty construction without a warning.
        let mut _temp = Mat::new();
        let mut rows = 0u;
        let mut _cols;
        $(
            rows += 1;
            _cols = 0u;
            $(
                _cols += 1;
                _temp.push($e);
            )+
        )*

        unsafe {
            _temp.set_rows(rows);
            _temp.set_cols(_cols);
        }

        _temp
    });
);

#[cfg(test)]
mod tests {
    extern crate test;

    use mat::Mat;

    #[test]
    fn index() {
        let a = mat![1f32, 2f32];
        assert_eq!(1.0, a[0][0]);
        assert_eq!(2.0, a[0][1]);

        let b = mat![1f32; 2f32];
        assert_eq!(1.0, b[0][0]);
        assert_eq!(2.0, b[1][0]);

        let m = mat![1f32, 2f32; 3f32, 4f32];
        assert_eq!(1.0, m[0][0]);
        assert_eq!(2.0, m[0][1]);
        assert_eq!(3.0, m[1][0]);
        assert_eq!(4.0, m[1][1]);
    }

    #[test]
    fn mul_vec() {
        let a = mat![1f32, -2f32; 2f32, -4f32];
        let x = vec![2f32, 1f32];

        assert_eq!(a * x, vec![0f32, 0f32]);
    }

    #[test]
    fn mul_mat() {
        let a = mat![1f32, -2f32; 2f32, -4f32];
        let b = mat![1f32, -2f32; 2f32, -4f32];

        let result = mat![-3f32, 6f32; -6f32, 12f32];
        assert_eq!(a * b, result);
    }
}
<commit_msg>Rename macro<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![macro_use]

use std::fmt;
use std::mem;
use std::num::NumCast;
use std::ops::Index;
use std::raw::Slice;
use std::slice::AsSlice;
use blas::default::Default;
use blas::matrix::Matrix;
use blas::matrix::ops::{
    Gemm,
};
use blas::matrix_vector::ops::{
    Gemv,
};
use blas::vector::ops::Copy;

pub struct Mat<T> {
    rows: uint,
    cols: uint,
    data: Vec<T>,
}

impl<T> Mat<T> {
    #[inline]
    pub fn new() -> Mat<T> {
        let _data: Vec<T> = Vec::new();
        Mat { rows: 0, cols: 0, data: _data }
    }

    #[inline]
    pub fn from_vec(rows: uint, cols: uint, vec: Vec<T>) -> Mat<T> {
        Mat { rows: rows, cols: cols, data: vec }
    }

    #[inline]
    pub fn zero(rows: uint, cols: uint) -> Mat<T> {
        let mut _data: Vec<T> = Vec::with_capacity(rows * cols);
        unsafe { _data.set_len(rows * cols); }
        Mat { rows: rows, cols: cols, data: _data}
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        self.data.push(value);
    }

    #[inline]
    pub fn rows(&self) -> uint {
        self.rows
    }

    #[inline]
    pub fn cols(&self) -> uint {
        self.cols
    }

    #[inline]
    pub unsafe fn set_rows(&mut self, rows: uint) {
        self.rows = rows;
    }

    #[inline]
    pub unsafe fn set_cols(&mut self, cols: uint) {
        self.cols = cols;
    }

    #[inline]
    pub unsafe fn as_slice<'a>(&'a self) -> &'a [T] {
        self.data.as_slice()
    }

    #[inline]
    pub unsafe fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.data.as_mut_slice()
    }
}

impl<T> Matrix<T> for Mat<T> {
    #[inline]
    fn rows(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.rows());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn cols(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.cols());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T {
        unsafe { self.as_slice().as_ptr() }
    }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T {
        unsafe { self.as_mut_slice().as_mut_ptr() }
    }
}

impl<T: Copy> Clone for Mat<T> {
    fn clone(&self) -> Mat<T> {
        let n = self.rows * self.cols;

        let mut x = Vec::with_capacity(n);
        unsafe {
            Copy::copy(&self.data, &mut x);
            x.set_len(n);
        }

        Mat::from_vec(self.rows, self.cols, x)
    }
}

impl<T: PartialEq> PartialEq for Mat<T> {
    fn eq(&self, other: &Mat<T>) -> bool {
        self.rows == other.rows &&
        self.cols == other.cols &&
        self.data == other.data
    }
}

impl<T> Index<uint, [T]> for Mat<T> {
    fn index<'a>(&'a self, index: &uint) -> &'a [T] {
        unsafe {
            let ptr = self.data.as_slice().as_ptr().offset((*index * self.cols) as int);
            mem::transmute(Slice { data: ptr, len: self.cols })
        }
    }
}

impl<T: fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in range(0u, self.rows) {
            match writeln!(f, "{}", &self[i]) {
                Ok(_) => (),
                x => return x,
            }
        }

        Ok(())
    }
}

impl<'a, T> Mul<&'a Vec<T>, Vec<T>> for Mat<T>
where T: Default + Gemv {
    fn mul(&self, x: &'a Vec<T>) -> Vec<T> {
        let mut result = Vec::with_capacity(self.rows);

        Gemv::gemv(&Default::one(), self, x, &Default::zero(), &mut result);
        unsafe { result.set_len(self.rows); }

        result
    }
}

impl<'a, T> Mul<&'a Mat<T>, Mat<T>> for Mat<T>
where T: Default + Gemm {
    fn mul(&self, b: &'a Mat<T>) -> Mat<T> {
        let mut result = Mat::zero(self.cols, b.rows);
        Gemm::gemm(&Default::one(), self, b, &Default::zero(), &mut result);

        result
    }
}

#[macro_export]
macro_rules! mat(
    ($($($e: expr),+);*) => ({
        // leading _ to allow empty construction without a warning.
        let mut _temp = Mat::new();
        let mut rows = 0u;
        let mut _cols;
        $(
            rows += 1;
            _cols = 0u;
            $(
                _cols += 1;
                _temp.push($e);
            )+
        )*

        unsafe {
            _temp.set_rows(rows);
            _temp.set_cols(_cols);
        }

        _temp
    });
);

#[cfg(test)]
mod tests {
    extern crate test;

    use mat::Mat;

    #[test]
    fn index() {
        let a = mat![1f32, 2f32];
        assert_eq!(1.0, a[0][0]);
        assert_eq!(2.0, a[0][1]);

        let b = mat![1f32; 2f32];
        assert_eq!(1.0, b[0][0]);
        assert_eq!(2.0, b[1][0]);

        let m = mat![1f32, 2f32; 3f32, 4f32];
        assert_eq!(1.0, m[0][0]);
        assert_eq!(2.0, m[0][1]);
        assert_eq!(3.0, m[1][0]);
        assert_eq!(4.0, m[1][1]);
    }

    #[test]
    fn mul_vec() {
        let a = mat![1f32, -2f32; 2f32, -4f32];
        let x = vec![2f32, 1f32];

        assert_eq!(a * x, vec![0f32, 0f32]);
    }

    #[test]
    fn mul_mat() {
        let a = mat![1f32, -2f32; 2f32, -4f32];
        let b = mat![1f32, -2f32; 2f32, -4f32];

        let result = mat![-3f32, 6f32; -6f32, 12f32];
        assert_eq!(a * b, result);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![macro_escape]

extern crate blas;

use std::fmt;
use std::mem;
use std::num::NumCast;
use std::ops::Index;
use std::raw::Slice;
use std::slice::AsSlice;
use self::blas::default::Default;
use self::blas::matrix::Matrix;
use self::blas::matrix_vector::ops::{
    Gemv,
};
use self::blas::vector::ops::Copy;

pub struct Mat<T> {
    rows: uint,
    cols: uint,
    data: Vec<T>,
}

impl<T> Mat<T> {
    #[inline]
    pub fn new() -> Mat<T> {
        let _data: Vec<T> = Vec::new();
        Mat { rows: 0, cols: 0, data: _data }
    }

    #[inline]
    pub fn from_vec(rows: uint, cols: uint, vec: Vec<T>) -> Mat<T> {
        Mat { rows: rows, cols: cols, data: vec }
    }

    #[inline]
    pub fn zero(rows: uint, cols: uint) -> Mat<T> {
        let mut _data: Vec<T> = Vec::with_capacity(rows * cols);
        unsafe { _data.set_len(rows * cols); }
        Mat { rows: rows, cols: cols, data: _data}
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        self.data.push(value);
    }

    #[inline]
    pub fn rows(&self) -> uint {
        self.rows
    }

    #[inline]
    pub fn cols(&self) -> uint {
        self.cols
    }

    #[inline]
    pub unsafe fn set_rows(&mut self, rows: uint) {
        self.rows = rows;
    }

    #[inline]
    pub unsafe fn set_cols(&mut self, cols: uint) {
        self.cols = cols;
    }

    #[inline]
    pub unsafe fn as_slice<'a>(&'a self) -> &'a [T] {
        self.data.as_slice()
    }

    #[inline]
    pub unsafe fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.data.as_mut_slice()
    }
}

impl<T> Matrix<T> for Mat<T> {
    #[inline]
    fn rows(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.rows());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn cols(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.cols());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T {
        unsafe { self.as_slice().as_ptr() }
    }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T {
        unsafe { self.as_mut_slice().as_mut_ptr() }
    }
}

impl<T: Copy> Clone for Mat<T> {
    fn clone(&self) -> Mat<T> {
        let n = self.rows * self.cols;

        let mut x = Vec::with_capacity(n);
        unsafe {
            Copy::copy(&self.data, &mut x);
            x.set_len(n);
        }

        Mat::from_vec(self.rows, self.cols, x)
    }
}

impl<T: PartialEq> PartialEq for Mat<T> {
    fn eq(&self, other: &Mat<T>) -> bool {
        self.rows == other.rows &&
        self.cols == other.cols &&
        self.data == other.data
    }
}

impl<T> Index<uint, [T]> for Mat<T> {
    fn index<'a>(&'a self, index: &uint) -> &'a [T] {
        unsafe {
            let ptr = self.data.as_slice().as_ptr().offset((*index * self.cols) as int);
            mem::transmute(Slice { data: ptr, len: self.cols })
        }
    }
}

impl<T: fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in range(0u, self.rows) {
            match writeln!(f, "{}", &self[i]) {
                Ok(_) => (),
                x => return x,
            }
        }

        Ok(())
    }
}

impl<T: Default + Gemv> Mul<Vec<T>, Vec<T>> for Mat<T> {
    fn mul(&self, x: &Vec<T>) -> Vec<T> {
        let mut result = Vec::with_capacity(self.rows);
        let one: T = Default::one();
        let zero: T = Default::zero();

        Gemv::gemv(&one, self, x, &zero, &mut result);
        unsafe { result.set_len(self.rows); }

        result
    }
}

#[macro_export]
macro_rules! mat(
    ($([$($e: expr),+]),*) => ({
        // leading _ to allow empty construction without a warning.
        let mut _temp = Mat::new();
        let mut rows = 0u;
        let mut _cols;
        $(
            rows += 1;
            _cols = 0u;
            $(
                _cols += 1;
                _temp.push($e);
            )+
        )*

        unsafe {
            _temp.set_rows(rows);
            _temp.set_cols(_cols);
        }

        _temp
    });
)

#[cfg(test)]
mod tests {
    extern crate test;

    use mat::Mat;

    #[test]
    fn index() {
        let m = mat![[1f32,2f32],[3f32,4f32]];

        assert_eq!(1.0, m[0][0]);
        assert_eq!(2.0, m[0][1]);
        assert_eq!(3.0, m[1][0]);
        assert_eq!(4.0, m[1][1]);
    }

    #[test]
    fn mul_vec() {
        let a = mat![
            [1f32, -2f32],
            [2f32, -4f32]
        ];
        let x = vec![2f32, 1f32];

        assert_eq!(a * x, vec![0f32, 0f32]);
    }
}
<commit_msg>Clean Mat impls<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![macro_escape]

extern crate blas;

use std::fmt;
use std::mem;
use std::num::NumCast;
use std::ops::Index;
use std::raw::Slice;
use std::slice::AsSlice;
use self::blas::default::Default;
use self::blas::matrix::Matrix;
use self::blas::matrix_vector::ops::{
    Gemv,
};
use self::blas::vector::ops::Copy;

pub struct Mat<T> {
    rows: uint,
    cols: uint,
    data: Vec<T>,
}

impl<T> Mat<T> {
    #[inline]
    pub fn new() -> Mat<T> {
        let _data: Vec<T> = Vec::new();
        Mat { rows: 0, cols: 0, data: _data }
    }

    #[inline]
    pub fn from_vec(rows: uint, cols: uint, vec: Vec<T>) -> Mat<T> {
        Mat { rows: rows, cols: cols, data: vec }
    }

    #[inline]
    pub fn zero(rows: uint, cols: uint) -> Mat<T> {
        let mut _data: Vec<T> = Vec::with_capacity(rows * cols);
        unsafe { _data.set_len(rows * cols); }
        Mat { rows: rows, cols: cols, data: _data}
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        self.data.push(value);
    }

    #[inline]
    pub fn rows(&self) -> uint {
        self.rows
    }

    #[inline]
    pub fn cols(&self) -> uint {
        self.cols
    }

    #[inline]
    pub unsafe fn set_rows(&mut self, rows: uint) {
        self.rows = rows;
    }

    #[inline]
    pub unsafe fn set_cols(&mut self, cols: uint) {
        self.cols = cols;
    }

    #[inline]
    pub unsafe fn as_slice<'a>(&'a self) -> &'a [T] {
        self.data.as_slice()
    }

    #[inline]
    pub unsafe fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.data.as_mut_slice()
    }
}

impl<T> Matrix<T> for Mat<T> {
    #[inline]
    fn rows(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.rows());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn cols(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.cols());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T {
        unsafe { self.as_slice().as_ptr() }
    }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T {
        unsafe { self.as_mut_slice().as_mut_ptr() }
    }
}

impl<T: Copy> Clone for Mat<T> {
    fn clone(&self) -> Mat<T> {
        let n = self.rows * self.cols;

        let mut x = Vec::with_capacity(n);
        unsafe {
            Copy::copy(&self.data, &mut x);
            x.set_len(n);
        }

        Mat::from_vec(self.rows, self.cols, x)
    }
}

impl<T: PartialEq> PartialEq for Mat<T> {
    fn eq(&self, other: &Mat<T>) -> bool {
        self.rows == other.rows &&
        self.cols == other.cols &&
        self.data == other.data
    }
}

impl<T> Index<uint, [T]> for Mat<T> {
    fn index<'a>(&'a self, index: &uint) -> &'a [T] {
        unsafe {
            let ptr = self.data.as_slice().as_ptr().offset((*index * self.cols) as int);
            mem::transmute(Slice { data: ptr, len: self.cols })
        }
    }
}

impl<T: fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in range(0u, self.rows) {
            match writeln!(f, "{}", &self[i]) {
                Ok(_) => (),
                x => return x,
            }
        }

        Ok(())
    }
}

impl<T> Mul<Vec<T>, Vec<T>> for Mat<T>
where T: Default + Gemv {
    fn mul(&self, x: &Vec<T>) -> Vec<T> {
        let mut result = Vec::with_capacity(self.rows);
        let one: T = Default::one();
        let zero: T = Default::zero();

        Gemv::gemv(&one, self, x, &zero, &mut result);
        unsafe { result.set_len(self.rows); }

        result
    }
}

#[macro_export]
macro_rules! mat(
    ($([$($e: expr),+]),*) => ({
        // leading _ to allow empty construction without a warning.
        let mut _temp = Mat::new();
        let mut rows = 0u;
        let mut _cols;
        $(
            rows += 1;
            _cols = 0u;
            $(
                _cols += 1;
                _temp.push($e);
            )+
        )*

        unsafe {
            _temp.set_rows(rows);
            _temp.set_cols(_cols);
        }

        _temp
    });
)

#[cfg(test)]
mod tests {
    extern crate test;

    use mat::Mat;

    #[test]
    fn index() {
        let m = mat![[1f32,2f32],[3f32,4f32]];

        assert_eq!(1.0, m[0][0]);
        assert_eq!(2.0, m[0][1]);
        assert_eq!(3.0, m[1][0]);
        assert_eq!(4.0, m[1][1]);
    }

    #[test]
    fn mul_vec() {
        let a = mat![
            [1f32, -2f32],
            [2f32, -4f32]
        ];
        let x = vec![2f32, 1f32];

        assert_eq!(a * x, vec![0f32, 0f32]);
    }
}
<|endoftext|>


<commit_before>//! Traits for text representations of boards and moves, which may be used for [Portable game notation][1].
//!
//! The terminology used in this module is specific to chess and chess variants, but it can be implemented for any game.
//!
//! [1]: https://en.wikipedia.org/wiki/Portable_Game_Notation

use search_algorithms::board;
use std::error;
use std::fmt;

/// A list of general categories of errors related to pgn parsing.
///
/// This list is intended to grow over time and it is not recommended to exhaustively match against it.
///
/// It is used with the [`Error`] type.
///
/// [`Error`]: struct.Error.html
#[derive(Clone, Copy, Eq, PartialEq, Debug, PartialOrd, Ord)]
pub enum ErrorKind {
    ParseError,
    AmbiguousMove,
    IllegalMove,
    IllegalPosition,
    Other,
}

/// The error type for operations on UciBoard.
///
/// The error can be created with an arbitrary payload and optionally an underlying source error for error chaining.
#[derive(Debug)]
pub struct Error {
    kind: ErrorKind,
    error: Box<dyn error::Error + Send + Sync>,
    source: Option<Box<dyn error::Error + Send + Sync>>,
}

impl Error {
    pub fn new<E>(kind: ErrorKind, error: E) -> Error
    where E: Into<Box<dyn error::Error + Send + Sync>> {
        Error { kind, error: error.into(), source: None}
    }

    pub fn new_caused_by<E, F>(kind: ErrorKind, error: E, source: F) -> Error
    where E: Into<Box<dyn error::Error + Send + Sync>>,
          F: Into<Box<dyn error::Error + Send + Sync>> {
        Error { kind, error: error.into(), source: Some(source.into())}
    }
}

impl error::Error for Error {}

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match self.kind {
            ErrorKind::ParseError => write!(fmt, "Parse error. "),
            ErrorKind::AmbiguousMove => write!(fmt, "Ambiguous move. "),
            ErrorKind::IllegalMove => write!(fmt, "Illegal move. "),
            ErrorKind::IllegalPosition => write!(fmt, "Illegal position. "),
            ErrorKind::Other => Ok(()),
        }?;
        write!(fmt, "{}", self.error)?;
        if let Some(ref source) = self.source {
            write!(fmt, "\nCaused by: {}", source)?;
        }
        Ok(())
    }
}

pub trait UciBoard: Sized + board::Board {
    /// Constructs a board from [Forsyth–Edwards Notation][1].
    ///
    /// Extensions to this notation exist for all large chess variants
    ///
    /// [1]: https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation
    fn from_fen(fen: &str) -> Result<Self, Error>;

    /// Creates a string representation of the board in [Forsyth–Edwards Notation][1].
    ///
    /// Extensions to this notation exist for all large chess variants.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation
    fn to_fen(&self) -> String;

    /// Construct a game move from [Standard Algebraic Notation][1], specifically the format used in [pgn notation][2].
    ///
    /// Extensions to this notation exist for all large chess variants.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Algebraic_notation_(chess)
    /// [2]: https://en.wikipedia.org/wiki/Portable_Game_Notation
    fn move_from_san(&self, input: &str) -> Result<Self::Move, Error>;

    /// Creates a string representation of the move in [Standard Algebraic Notation][1], specifically the format used in [pgn notation][2].
    ///
    /// Extensions to this notation exist for all large chess variants.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Algebraic_notation_(chess)
    /// [2]: https://en.wikipedia.org/wiki/Portable_Game_Notation
    fn move_to_san(&self, mv: &Self::Move) -> String;

    /// Construct a move from an alternative, [long algebraic notation][1].
    ///
    /// This is mostly used for chess and chess variations in the uci interface, or for convenient debugging.
    /// Implementations may simply wrap this function around `move_from_san` where appropriate.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Algebraic_notation_(chess)#Long_algebraic_notation
    fn move_from_lan(&self, input: &str) -> Result<Self::Move, Error>;

    /// Creates a string representation of the move in an alternative, [long algebraic notation][1].
    ///
    /// This is mostly used for chess and chess variations in the uci interface, or for convenient debugging.
    /// Implementations may simply wrap this function around `move_to_san` where appropriate.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Algebraic_notation_(chess)#Long_algebraic_notation
    fn move_to_lan(&self, mv: &Self::Move) -> String;

}<commit_msg>Improve pgn docs<commit_after>//! Data types for text representations of board positions and moves, which may be used for [Portable game notation][1].
//!
//! The terminology used in this module is specific to chess and chess variants, but it can be implemented for any game.
//!
//! [1]: https://en.wikipedia.org/wiki/Portable_Game_Notation

use search_algorithms::board;
use std::error;
use std::fmt;

/// A list of general categories of errors related to pgn parsing.
///
/// This list is intended to grow over time and it is not recommended to exhaustively match against it.
///
/// It is used with the [`Error`] type.
///
/// [`Error`]: struct.Error.html
#[derive(Clone, Copy, Eq, PartialEq, Debug, PartialOrd, Ord)]
pub enum ErrorKind {
    ParseError,
    AmbiguousMove,
    IllegalMove,
    IllegalPosition,
    IOError,
    Other,
}

/// The error type for operations on UciBoard.
///
/// The error can be created with an arbitrary payload and optionally an underlying source error for error chaining.
#[derive(Debug)]
pub struct Error {
    kind: ErrorKind,
    error: Box<dyn error::Error + Send + Sync>,
    source: Option<Box<dyn error::Error + Send + Sync>>,
}

impl Error {
    /// Returns a new error of the specific `ErrorKind` with an arbitrary payload.
    pub fn new<E>(kind: ErrorKind, error: E) -> Error
    where E: Into<Box<dyn error::Error + Send + Sync>> {
        Error { kind, error: error.into(), source: None}
    }

    /// Returns a new error of the specific `ErrorKind` with an arbitrary payload and source error.
    pub fn new_caused_by<E, F>(kind: ErrorKind, error: E, source: F) -> Error
    where E: Into<Box<dyn error::Error + Send + Sync>>,
          F: Into<Box<dyn error::Error + Send + Sync>> {
        Error { kind, error: error.into(), source: Some(source.into())}
    }
}

impl error::Error for Error {}

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match self.kind {
            ErrorKind::ParseError => write!(fmt, "Parse error. "),
            ErrorKind::AmbiguousMove => write!(fmt, "Ambiguous move. "),
            ErrorKind::IllegalMove => write!(fmt, "Illegal move. "),
            ErrorKind::IllegalPosition => write!(fmt, "Illegal position. "),
            ErrorKind::Other => Ok(()),
        }?;
        write!(fmt, "{}", self.error)?;
        if let Some(ref source) = self.source {
            write!(fmt, "\nCaused by: {}", source)?;
        }
        Ok(())
    }
}

/// Trait for text representations of board positions and moves.
///
/// The terminology used in this trait is specific to chess and chess variants, but it can be implemented for any game.
pub trait UciBoard: Sized + board::Board {
    /// Constructs a board from [Forsyth–Edwards Notation][1].
    ///
    /// Extensions to this notation exist for all large chess variants
    ///
    /// [1]: https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation
    fn from_fen(fen: &str) -> Result<Self, Error>;

    /// Returns a string representation of the board in [Forsyth–Edwards Notation][1].
    ///
    /// Extensions to this notation exist for all large chess variants.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation
    fn to_fen(&self) -> String;

    /// Construct a game move from [Standard Algebraic Notation][1], specifically the format used in [pgn notation][2].
    ///
    /// Extensions to this notation exist for all large chess variants.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Algebraic_notation_(chess)
    /// [2]: https://en.wikipedia.org/wiki/Portable_Game_Notation
    fn move_from_san(&self, input: &str) -> Result<Self::Move, Error>;

    /// Returns a string representation of the move in [Standard Algebraic Notation][1], specifically the format used in [pgn notation][2].
    ///
    /// Extensions to this notation exist for all large chess variants.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Algebraic_notation_(chess)
    /// [2]: https://en.wikipedia.org/wiki/Portable_Game_Notation
    fn move_to_san(&self, mv: &Self::Move) -> String;

    /// Construct a move from an alternative, [long algebraic notation][1].
    ///
    /// This is mostly used for chess and chess variations in the uci interface, or for convenient debugging.
    /// Implementations may simply wrap this function around `move_from_san` where appropriate.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Algebraic_notation_(chess)#Long_algebraic_notation
    fn move_from_lan(&self, input: &str) -> Result<Self::Move, Error>;

    /// Returns a string representation of the move in an alternative, [long algebraic notation][1].
    ///
    /// This is mostly used for chess and chess variations in the uci interface, or for convenient debugging.
    /// Implementations may simply wrap this function around `move_to_san` where appropriate.
    ///
    /// [1]: https://en.wikipedia.org/wiki/Algebraic_notation_(chess)#Long_algebraic_notation
    fn move_to_lan(&self, mv: &Self::Move) -> String;

}<|endoftext|>


<commit_before>use value::Value;
use block::BasicBlock;
use ffi::core;

/// A PHI node represents a value which is selected based on the predecessor of the current block.
pub type PhiNode = Value;

impl PhiNode {
  /// Adds an incoming value to the end of this PHI node.
  pub fn add_incoming(&self, val: &Value, block: &BasicBlock) {
    let mut values = vec![val.into()];
    let mut blocks = vec![block.into()];
    unsafe { core::LLVMAddIncoming(self.into(), values.as_mut_ptr(), blocks.as_mut_ptr(), 1) }.into()
  }

  /// Counts the number of incoming values attached to this PHI node.
  pub fn count_incoming(&self) -> u32 {
    unsafe { core::LLVMCountIncoming(self.into()) }
  }

  /// Gets an incoming value from this PHI node from a specific index.
  pub fn get_incoming_value(&self, index: u32) -> &Value {
    unsafe { core::LLVMGetIncomingValue(self.into(), index) }.into()
  }

  /// Gets an incoming basic block from this PHI node from a specific index.
  pub fn get_incoming_block(&self, index: u32) -> &BasicBlock {
    unsafe { core::LLVMGetIncomingBlock(self.into(), index) }.into()
  }
}<commit_msg>Make PHI nodes more type safe.<commit_after>use std::mem;
use std::ops::Deref;
use std::ptr;

use ffi::core;
use ffi::prelude::LLVMValueRef;

use block::BasicBlock;
use value::Value;
use util::CastFrom;

/// A PHI node represents a value which is selected based on the predecessor of the current block.
pub struct PhiNode;
native_ref!(&PhiNode = LLVMValueRef);

impl PhiNode {
  /// Adds an incoming value to the end of this PHI node.
  pub fn add_incoming(&self, val: &Value, block: &BasicBlock) {
    let mut values = vec![val.into()];
    let mut blocks = vec![block.into()];
    unsafe { core::LLVMAddIncoming(self.into(), values.as_mut_ptr(), blocks.as_mut_ptr(), 1) }.into()
  }

  /// Counts the number of incoming values attached to this PHI node.
  pub fn count_incoming(&self) -> u32 {
    unsafe { core::LLVMCountIncoming(self.into()) }
  }

  /// Gets an incoming value from this PHI node from a specific index.
  pub fn get_incoming_value(&self, index: u32) -> &Value {
    unsafe { core::LLVMGetIncomingValue(self.into(), index) }.into()
  }

  /// Gets an incoming basic block from this PHI node from a specific index.
  pub fn get_incoming_block(&self, index: u32) -> &BasicBlock {
    unsafe { core::LLVMGetIncomingBlock(self.into(), index) }.into()
  }
}

impl CastFrom for PhiNode {
  type From = Value;
  fn cast(value: &Value) -> Option<&PhiNode> {
    unsafe {
      let node = core::LLVMIsAPHINode(value.into());
      if node == ptr::null_mut() {
          None
      } else {
          Some(node.into())
      }
    }
  }
}

deref!(PhiNode, Value);<|endoftext|>


<commit_before>use std::fmt::{Display, Formatter, Error};

#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum SeqElem {
    // Listed alphabetically to make equality testing for groups of seqeuences easier.
    Const(i32),
    Div(i32),
    Mod(i32),
    Mult(i32),
    Plus(i32),
}

impl Display for SeqElem {
    fn fmt(&self, mut fmt: &mut Formatter) -> Result<(), Error> {
        match *self {
            SeqElem::Plus(i) if i < 0 => write!(fmt, "- {}", i.abs()),
            SeqElem::Plus(i) => write!(fmt, "+ {}", i),
            SeqElem::Mult(i) => write!(fmt, "* {}", i),
            SeqElem::Div(i) => write!(fmt, "/ {}", i),
            SeqElem::Mod(i) => write!(fmt, "% {}", i),
            SeqElem::Const(i) => write!(fmt, "= {}", i),
        }
    }
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Seq(Vec<SeqElem>);

impl Seq {
    pub fn new(elems: Vec<SeqElem>) -> Self {
        Seq(elems)
    }

    pub fn empty() -> Self {
        Seq(Vec::new())
    }

    pub fn extend_each<T>(&self, iter: T) -> Vec<Self> where T: Iterator<Item=SeqElem> {
        iter.map(|elem| {
            let mut v = self.0.clone();
            v.push(elem);
            Seq(v)
        }).collect()
    }
}

impl Display for Seq {
    fn fmt(&self, mut fmt: &mut Formatter) -> Result<(), Error> {
        for (i, elem) in self.0.iter().enumerate() {
            if i != 0 {
                try!(write!(fmt, ", "));
            }

            try!(write!(fmt, "{}", elem));
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::SeqElem::*;
    use super::Seq;

    #[test]
    fn fmt_seq_elem_plus() {
        assert_eq!("+ 0", format!("{}", Plus(0)));
        assert_eq!("+ 4", format!("{}", Plus(4)));
    }

    #[test]
    fn fmt_seq_elem_minus() {
        assert_eq!("- 1", format!("{}", Plus(-1)));
        assert_eq!("- 4", format!("{}", Plus(-4)));
    }

    #[test]
    fn fmt_seq_elem_mult() {
        assert_eq!("* -4", format!("{}", Mult(-4)));
        assert_eq!("* 4", format!("{}", Mult(4)));
    }

    #[test]
    fn fmt_seq_elem_div() {
        assert_eq!("/ -4", format!("{}", Div(-4)));
        assert_eq!("/ 4", format!("{}", Div(4)));
    }

    #[test]
    fn fmt_seq_elem_mod() {
        assert_eq!("% -4", format!("{}", Mod(-4)));
        assert_eq!("% 4", format!("{}", Mod(4)));
    }

    #[test]
    fn fmt_seq_elem_const() {
        assert_eq!("= -4", format!("{}", Const(-4)));
        assert_eq!("= 4", format!("{}", Const(4)));
    }

    #[test]
    fn fmt_seq() {
        assert_eq!("", format!("{}", Seq(Vec::new())));
        assert_eq!("+ 4", format!("{}", Seq(vec![Plus(4)])));
        assert_eq!("+ 4, % -6", format!("{}", Seq::new(vec![Plus(4), Mod(-6)])));
        assert_eq!("+ 4, % -6, - 12, * 42, / 3, = 9", format!("{}", Seq(vec![Plus(4), Mod(-6), Plus(-12), Mult(42), Div(3), Const(9)])));
    }
}
<commit_msg>remove unnecessary whitespace from display<commit_after>use std::fmt::{Display, Formatter, Error};

#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum SeqElem {
    // Listed alphabetically to make equality testing for groups of seqeuences easier.
    Const(i32),
    Div(i32),
    Mod(i32),
    Mult(i32),
    Plus(i32),
}

impl Display for SeqElem {
    fn fmt(&self, mut fmt: &mut Formatter) -> Result<(), Error> {
        match *self {
            SeqElem::Plus(i) if i < 0 => write!(fmt, "-{}", i.abs()),
            SeqElem::Plus(i) => write!(fmt, "+{}", i),
            SeqElem::Mult(i) => write!(fmt, "*{}", i),
            SeqElem::Div(i) => write!(fmt, "/{}", i),
            SeqElem::Mod(i) => write!(fmt, "%{}", i),
            SeqElem::Const(i) => write!(fmt, "={}", i),
        }
    }
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Seq(Vec<SeqElem>);

impl Seq {
    pub fn new(elems: Vec<SeqElem>) -> Self {
        Seq(elems)
    }

    pub fn empty() -> Self {
        Seq(Vec::new())
    }

    pub fn extend_each<T>(&self, iter: T) -> Vec<Self> where T: Iterator<Item=SeqElem> {
        iter.map(|elem| {
            let mut v = self.0.clone();
            v.push(elem);
            Seq(v)
        }).collect()
    }
}

impl Display for Seq {
    fn fmt(&self, mut fmt: &mut Formatter) -> Result<(), Error> {
        for (i, elem) in self.0.iter().enumerate() {
            if i != 0 {
                try!(write!(fmt, ", "));
            }

            try!(write!(fmt, "{}", elem));
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::SeqElem::*;
    use super::Seq;

    #[test]
    fn fmt_seq_elem_plus() {
        assert_eq!("+0", format!("{}", Plus(0)));
        assert_eq!("+4", format!("{}", Plus(4)));
    }

    #[test]
    fn fmt_seq_elem_minus() {
        assert_eq!("-1", format!("{}", Plus(-1)));
        assert_eq!("-4", format!("{}", Plus(-4)));
    }

    #[test]
    fn fmt_seq_elem_mult() {
        assert_eq!("*-4", format!("{}", Mult(-4)));
        assert_eq!("*4", format!("{}", Mult(4)));
    }

    #[test]
    fn fmt_seq_elem_div() {
        assert_eq!("/-4", format!("{}", Div(-4)));
        assert_eq!("/4", format!("{}", Div(4)));
    }

    #[test]
    fn fmt_seq_elem_mod() {
        assert_eq!("%-4", format!("{}", Mod(-4)));
        assert_eq!("%4", format!("{}", Mod(4)));
    }

    #[test]
    fn fmt_seq_elem_const() {
        assert_eq!("=-4", format!("{}", Const(-4)));
        assert_eq!("=4", format!("{}", Const(4)));
    }

    #[test]
    fn fmt_seq() {
        assert_eq!("", format!("{}", Seq(Vec::new())));
        assert_eq!("+4", format!("{}", Seq(vec![Plus(4)])));
        assert_eq!("+4, %-6", format!("{}", Seq::new(vec![Plus(4), Mod(-6)])));
        assert_eq!("+4, %-6, -12, *42, /3, =9", format!("{}", Seq(vec![Plus(4), Mod(-6), Plus(-12), Mult(42), Div(3), Const(9)])));
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use getrandom::getrandom;

use poly::{eval, generate, y_intercept};

/// Split a secret into N shares, of which K are required to re-combine. Returns
/// a map of share IDs to share values.
pub fn split(n: u8, k: u8, secret: &[u8]) -> HashMap<u8, Vec<u8>> {
    // Generate a random K-degree polynomial for each byte of the secret.
    let polys = secret
        .iter()
        .map(|&b| generate((k - 1) as usize, b, getrandom))
        .collect::<Vec<Vec<u8>>>();

    // Collect the evaluation of each polynomial with the share ID as the input.
    (1..=n)
        .map(|id| (id, polys.iter().map(|p| eval(p, id)).collect()))
        .collect()
}

/// Combine a map of share IDs into the original secret.
///
/// N.B.: There is no way to know if this is successful or not.
pub fn combine<S: ::std::hash::BuildHasher>(shares: &HashMap<u8, Vec<u8>, S>) -> Vec<u8> {
    let len = shares.values().next().unwrap().len();
    if shares.values().any(|v| v.len() != len) {
        panic!("mismatched share lengths")
    }

    (0..len)
        .map(|i| y_intercept(shares.iter().map(|(&id, v)| (id, v[i])).collect()))
        .collect()
}

#[cfg(test)]
mod test {
    extern crate itertools;

    use super::*;

    use self::itertools::Itertools;

    #[test]
    fn test_split() {
        let secret = vec![1, 2, 3, 4, 5];
        let splits = split(5, 3, &secret);

        for i in 5..=3 {
            for keys in splits.keys().combinations(i) {
                let mut subset = HashMap::new();
                for key in keys {
                    subset.insert(*key, splits.get(key).unwrap().to_vec());
                }
                assert_eq!(combine(&subset), secret);
            }
        }

        for i in 2..=1 {
            for keys in splits.keys().combinations(i) {
                let mut subset = HashMap::new();
                for key in keys {
                    subset.insert(*key, splits.get(key).unwrap().to_vec());
                }
                assert_ne!(combine(&subset), secret);
            }
        }
    }

    #[test]
    fn test_combine() {
        let mut shares = HashMap::new();
        shares.insert(1, vec![64, 163, 216, 189, 193]);
        shares.insert(3, vec![194, 250, 117, 212, 82]);
        shares.insert(5, vec![95, 17, 153, 111, 252]);

        assert_eq!(combine(&shares), vec![1, 2, 3, 4, 5])
    }
}
<commit_msg>Destructure when possible.<commit_after>use std::collections::HashMap;

use getrandom::getrandom;

use poly::{eval, generate, y_intercept};

/// Split a secret into N shares, of which K are required to re-combine. Returns
/// a map of share IDs to share values.
pub fn split(n: u8, k: u8, secret: &[u8]) -> HashMap<u8, Vec<u8>> {
    // Generate a random K-degree polynomial for each byte of the secret.
    let polys = secret
        .iter()
        .map(|&b| generate((k - 1) as usize, b, getrandom))
        .collect::<Vec<Vec<u8>>>();

    // Collect the evaluation of each polynomial with the share ID as the input.
    (1..=n)
        .map(|id| (id, polys.iter().map(|p| eval(p, id)).collect()))
        .collect()
}

/// Combine a map of share IDs into the original secret.
///
/// N.B.: There is no way to know if this is successful or not.
pub fn combine<S: ::std::hash::BuildHasher>(shares: &HashMap<u8, Vec<u8>, S>) -> Vec<u8> {
    let len = shares.values().next().unwrap().len();
    if shares.values().any(|v| v.len() != len) {
        panic!("mismatched share lengths")
    }

    (0..len)
        .map(|i| y_intercept(shares.iter().map(|(&id, v)| (id, v[i])).collect()))
        .collect()
}

#[cfg(test)]
mod test {
    extern crate itertools;

    use super::*;

    use self::itertools::Itertools;

    #[test]
    fn test_split() {
        let secret = vec![1, 2, 3, 4, 5];
        let splits = split(5, 3, &secret);

        for i in 5..=3 {
            for keys in splits.keys().combinations(i) {
                let mut subset = HashMap::new();
                for &key in keys {
                    subset.insert(key, splits.get(&key).unwrap().to_vec());
                }
                assert_eq!(combine(&subset), secret);
            }
        }

        for i in 2..=1 {
            for keys in splits.keys().combinations(i) {
                let mut subset = HashMap::new();
                for &key in keys {
                    subset.insert(key, splits.get(&key).unwrap().to_vec());
                }
                assert_ne!(combine(&subset), secret);
            }
        }
    }

    #[test]
    fn test_combine() {
        let mut shares = HashMap::new();
        shares.insert(1, vec![64, 163, 216, 189, 193]);
        shares.insert(3, vec![194, 250, 117, 212, 82]);
        shares.insert(5, vec![95, 17, 153, 111, 252]);

        assert_eq!(combine(&shares), vec![1, 2, 3, 4, 5])
    }
}
<|endoftext|>