Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Heavily based on https://rust-unofficial.github.io/too-many-lists
- use std::fmt;
- use std::iter::{FromIterator, IntoIterator};
- #[derive(Debug)]
- struct LinkedList<T> {
- head: Option<Box<Node<T>>>,
- }
- #[derive(Debug)]
- struct Node<T> {
- data: T,
- next: Option<Box<Node<T>>>,
- }
- struct LinkedListIterator<'a, T> {
- next: Option<&'a Node<T>>,
- }
- struct LinkedListMutIterator<'a, T> {
- next: Option<&'a mut Node<T>>,
- }
- struct LinkedListIntoIter<T>(LinkedList<T>);
- impl<T> LinkedList<T> {
- fn pop(&mut self) -> Option<T> {
- self.head.take().map(|node| {
- self.head = node.next;
- node.data
- })
- }
- fn iter(&self) -> LinkedListIterator<T> {
- LinkedListIterator {
- next: self.head.as_ref().map::<&Node<T>, _>(|node| &node),
- }
- }
- fn iter_mut(&mut self) -> LinkedListMutIterator<T> {
- LinkedListMutIterator {
- // How to use the "turbofish" here?
- next: self.head.as_mut().map(|node| &mut **node),
- }
- }
- }
- impl<T> Drop for LinkedList<T> {
- fn drop(&mut self) {
- let mut cursor = self.head.take();
- while let Some(mut node) = cursor {
- cursor = node.next.take();
- }
- }
- }
- impl<T> IntoIterator for LinkedList<T> {
- type Item = T;
- type IntoIter = LinkedListIntoIter<Self::Item>;
- fn into_iter(self) -> Self::IntoIter {
- LinkedListIntoIter(self)
- }
- }
- impl<'a, T> Iterator for LinkedListIterator<'a, T> {
- type Item = &'a T;
- fn next(&mut self) -> Option<Self::Item> {
- self.next.take().map(|node| {
- self.next = node.next.as_ref().map::<&Node<T>, _>(|node| &node);
- &node.data
- })
- }
- }
- impl<'a, T> Iterator for LinkedListMutIterator<'a, T> {
- type Item = &'a mut T;
- fn next(&mut self) -> Option<Self::Item> {
- self.next.take().map(|node| {
- self.next = node.next.as_mut().map(|node| &mut **node);
- &mut node.data
- })
- }
- }
- impl<T> Iterator for LinkedListIntoIter<T> {
- type Item = T;
- #[inline(always)]
- fn next(&mut self) -> Option<Self::Item> {
- self.0.pop()
- }
- }
- impl<T> FromIterator<T> for LinkedList<T>
- where
- T: Copy,
- {
- fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
- // Is there a non-ugly way to do this?
- let mut list = LinkedList { head: None };
- let mut prev: &mut Option<Box<Node<T>>> = &mut None;
- for item in iter {
- let current = Some(Box::new(Node {
- data: item,
- next: None,
- }));
- match *prev {
- None => {
- list.head = current;
- prev = &mut list.head;
- }
- Some(ref mut v) => {
- v.next = current;
- prev = &mut v.next;
- }
- }
- }
- list
- }
- }
- impl<T> fmt::Display for LinkedList<T>
- where
- T: fmt::Display,
- {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "[")?;
- for (i, v) in self.iter().enumerate() {
- if i != 0 {
- write!(f, ", ")?;
- }
- write!(f, "{}", v)?;
- }
- write!(f, "]")
- }
- }
- fn main() {
- // let list = LinkedList {
- // head: Some(Box::new(Node {
- // data: 1u8,
- // next: Some(Box::new(Node {
- // data: 2u8,
- // next: Some(Box::new(Node {
- // data: 3u8,
- // next: None,
- // })),
- // })),
- // })),
- // };
- // for elem in list.iter() {
- // println!("{}", elem);
- // }
- // FromIter:
- let mut list: LinkedList<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9].iter().copied().collect();
- println!("{}\n", list);
- // Iter:
- for elem in list.iter().step_by(2).take(3).map(|&v| v * v * v) {
- println!("{}", elem);
- }
- // IterMut:
- for elem in list.iter_mut() {
- *elem *= 5;
- }
- println!();
- // IntoIter:
- for elem in list {
- println!("{}", elem);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement