kudzu 0.1.0

concurrent, grow-only data structures
Documentation
use std::marker::PhantomData;
use std::mem;
use std::ptr::{self, NonNull};

use super::{Ptr, Node};

pub(super) struct Nodes<'a, T> {
    ptr: Ptr<Node<T>>,
    _marker: PhantomData<&'a T>,
}

impl<'a, T> Nodes<'a, T> {
    pub(super) fn new(ptr: Ptr<Node<T>>) -> Nodes<'a, T> {
        Nodes { ptr, _marker: PhantomData }
    }
}

impl<'a, T> Iterator for Nodes<'a, T> {
    type Item = &'a Node<T>;
    fn next(&mut self) -> Option<&'a Node<T>> {
        unsafe {
            let ptr: NonNull<Node<T>> = self.ptr.take()?;
            {
                let node: &Node<T> = ptr.as_ref();
                self.ptr = node.next();
            }
            mem::transmute(ptr)
        }
    }
}

pub(super) struct NodesMut<'a, T> {
    ptr: Ptr<Node<T>>,
    _marker: PhantomData<&'a mut T>,
}

impl<'a, T> NodesMut<'a, T> {
    pub(super) fn new(ptr: Ptr<Node<T>>) -> NodesMut<'a, T> {
        NodesMut { ptr, _marker: PhantomData }
    }
}

impl<'a, T> Iterator for NodesMut<'a, T> {
    type Item = &'a mut Node<T>;
    fn next(&mut self) -> Option<&'a mut Node<T>> {
        unsafe {
            let ptr: NonNull<Node<T>> = self.ptr.take()?;
            {
                let node: &Node<T> = ptr.as_ref();
                self.ptr = node.next();
            }
            mem::transmute(ptr)
        }
    }
}

pub struct Elems<'a, T> {
    pub(super) nodes: Nodes<'a, T>
}

impl<'a, T> Iterator for Elems<'a, T> {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
        self.nodes.next().map(|node| &node.inner.elem)
    }
}

pub struct ElemsMut<'a, T> {
    pub(super) nodes: NodesMut<'a, T>
}

impl<'a, T> Iterator for ElemsMut<'a, T> {
    type Item = &'a mut T;

    fn next(&mut self) -> Option<Self::Item> {
        self.nodes.next().map(|node| &mut node.inner.elem)
    }
}

pub struct IntoElems<T> {
    pub(super) ptr: Ptr<Node<T>>,
}

impl<T> Iterator for IntoElems<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        unsafe {
            let mut ptr = self.ptr.take()?;
            let node: &mut Node<T> = ptr.as_mut();
            self.ptr = node.next();
            let elem = ptr::read(&mut node.inner.elem as *mut T);
            node.dealloc();
            Some(elem)
        }
    }
}