Crate indexed

source ·
Expand description

This library provides a Vec-like, no reallocation collection named indexed::Pool. The pool’s reference can be obtained from one of its elements. It can be used as a memory pool, and library users do not need to store/pass the pool’s reference everywhere. The elements can be linked to each other using indexes rather than pointers.

Examples

use indexed::{Indexed,Pool};
use std::fmt::{self,Display,Formatter};

// A singly linked list of string.
struct List( Box<Pool<Node>> );

struct Node {
    next  : u32,
    index : u32,
    text  : &'static str,
}

unsafe impl Indexed for Node {
    fn null() -> usize { !0_u32 as usize }
    unsafe fn get_index( &self ) -> usize { self.index as usize }
    unsafe fn set_index( &mut self, index: usize ) { self.index = index as u32; }
}

impl List {
    fn new() -> Self { List( Pool::<Node>::new() )}

    fn head<'a>( &'a mut self, text: &'static str ) -> &'a mut Node {
        assert_eq!( self.0.new_index(), 0 );
        self.0.push( Node{
            next  : Node::null() as u32,
            index : 0, // the pool will set the actual index inside its `push()` method.
            text  ,
        });
        &mut self.0[0]
    }
}

impl Node {
    // The method does not need a parameter of `Pool`.
    fn add<'a>( &'a mut self, sib: &'static str ) -> &'a mut Self {
        let pool = unsafe { self.pool_mut() as *mut Pool<Node> };
        let index = unsafe{ (*pool).new_index() };
        self.next = index as u32;
        let pool = unsafe{ &mut *pool };
        pool.push( Node{
            next  : Node::null() as u32,
            index : Node::null() as u32, // the pool will set the actual index inside its `push()` method.
            text  : sib,
        });
        &mut pool[index]
    }
}

impl Display for List {
    fn fmt( &self, fmt: &mut Formatter ) -> fmt::Result {
        if self.0.new_index() != 0 {
            let mut curr = 0_usize;
            while curr != Node::null() {
                write!( fmt, "{} ", self.0[curr].text )?;
                curr = self.0[curr].next as usize;
            }
        }
        Ok(())
    }
}

let mut list = List::new();
list.head( "no" ).add( "need" ).add( "for" ).add( "pool" ).add( "parameter" );
assert_eq!( list.to_string(), "no need for pool parameter " );

Macros

Defines a wrapper type of a given type and implements Indexed for the wrapper.
Implements Indexed for a given type, using a given field as index storage of a given type which can be converted from/to usize using as.
Creates a Pool containing the arguments. The element type of the pool must be given explicitly inside the macro, of which the arguments is able to be converted into.

Structs

Immutable pool iterator
Mutable pool iterator
A Vec-like, no reallocation collection. Elements in a Pool should not be zero sized type, or the construction will panic.

Enums

Possible chunk sizes.

Traits

Type of elements in the Pool must implement this trait. Typically some integer field in the type must devote to storing the index in the pool, and it is not necessarily usize. For example, an index can be stored in u32 if 4194304K is enough for anybody.

Functions

Reflects the count of elements a chunk can hold.