Skip to content

Instantly share code, notes, and snippets.

@DutchGhost
Last active September 14, 2022 08:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DutchGhost/54bb3736a9e88d3a91503029011f8a07 to your computer and use it in GitHub Desktop.
Save DutchGhost/54bb3736a9e88d3a91503029011f8a07 to your computer and use it in GitHub Desktop.
Linked List generic over the ptr type
//#![feature(generic_associated_types)]
use std::ops::DerefMut;
trait PointerFamily {
type Pointer<'a, T: ?Sized + 'a>: DerefMut<Target = T>;
}
#[derive(Debug)]
struct RefFamily;
impl PointerFamily for RefFamily {
type Pointer<'a, T: ?Sized + 'a> = &'a mut T;
}
struct BoxFamily;
impl PointerFamily for BoxFamily {
type Pointer<'a, T: ?Sized + 'a> = Box<T>;
}
struct Node<'a, T: ?Sized + 'a, P: 'a>
where
P: PointerFamily,
{
next: Option<P::Pointer<'a, Node<'a, T, P>>>,
elem: T,
}
impl<'a, T: 'a, P: 'a> Node<'a, T, P>
where
P: PointerFamily,
{
pub fn new(elem: T) -> Self {
Self { next: None, elem }
}
}
struct List<'a, T: ?Sized + 'a, P: 'a>
where
P: PointerFamily,
{
head: Option<P::Pointer<'a, Node<'a, T, P>>>,
}
impl<'a, T: 'a, P: 'a> List<'a, T, P>
where
P: PointerFamily,
{
fn new() -> Self {
Self { head: None }
}
fn push(&mut self, mut node: P::Pointer<'a, Node<'a, T, P>>) {
node.next = self.head.take();
self.head = Some(node);
}
pub fn iter<'b>(&'b self) -> Iter<'b, 'a, T, P>
where
'a: 'b,
{
Iter {
next: self.head.as_deref(),
}
}
pub fn iter_mut<'b>(&'b mut self) -> IterMut<'b, 'a, T, P>
where
'a: 'b,
{
IterMut {
next: self.head.as_deref_mut(),
}
}
}
struct Iter<'a, 'b, T: 'a, P>
where
P: PointerFamily + 'a,
{
next: Option<&'a Node<'b, T, P>>,
}
impl<'a, 'b, T, P> Iterator for Iter<'a, 'b, T, P>
where
P: PointerFamily,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.next.map(|node| {
self.next = node.next.as_deref();
&node.elem
})
}
}
struct IterMut<'a, 'b, T: 'a, P>
where
P: PointerFamily + 'a,
{
next: Option<&'a mut Node<'b, T, P>>,
}
impl<'a, 'b, T, P> Iterator for IterMut<'a, 'b, T, P>
where
P: PointerFamily,
{
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
self.next.take().map(|node| {
self.next = node.next.as_deref_mut();
&mut node.elem
})
}
}
fn main() {
let mut l: List<i32, RefFamily> = List::new();
let mut n: Node<i32, RefFamily> = Node::new(20);
let mut n2: Node<i32, RefFamily> = Node::new(30);
l.push(&mut n);
l.push(&mut n2);
l.iter().for_each(|n| {
dbg!(n);
});
let mut l: List<i32, BoxFamily> = List::new();
let mut n: Node<i32, BoxFamily> = Node::new(20);
let mut n2: Node<i32, BoxFamily> = Node::new(30);
l.push(Box::new(n));
l.push(Box::new(n2));
l.iter_mut().for_each(|n| {
dbg!(n);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment