[][src]Crate indexed

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};
use std::pin::Pin;

// A singly linked list of string.
struct List( Pin<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

extrusive_indexed

Defines a wrapper type of a given type and implements Indexed for the wrapper.

impl_indexed

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.

pool

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

Iter

Immutable pool iterator

IterMut

Mutable pool iterator

Pool

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

Enums

ChunkLen

Possible chunk sizes.

Traits

Indexed

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

chunk_len

Reflects the count of elements a chunk can hold.