Struct indexed::Pool[][src]

pub struct Pool<T: Indexed> { /* fields omitted */ }

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

Implementations

impl<T: Indexed> Pool<T>[src]

pub fn new() -> Box<Self>[src]

Creates a new pool that drops its elements on destruction.

Panics

Panics if the type of element is ZST.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

static mut COUNT: usize = 0;

struct Name { index: usize, text: String }

impl_indexed!{ Name{ index: usize }}

impl Drop for Name { fn drop( &mut self ) { unsafe{ COUNT += 1; }}}

impl From<&'static str> for Name {
    fn from( s: &'static str ) -> Self {
        Name{ index: <Self as Indexed>::null(), text: s.to_string() }
    }
}

{ let pool = pool!( Name[ "foo", "bar", "baz" ]); }

assert_eq!( unsafe{ COUNT }, 3 );

pub fn new_unmanaged() -> Box<Self>[src]

Creates a new pool that does not drop its elements on destruction. It is up to the user to drop the elements manually to avoid memory leaks.

Panics

Panics if the type of element is ZST.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

static mut COUNT: usize = 0;

struct Name { index: usize, text: String }

impl_indexed!{ Name{ index: usize }}

impl Drop for Name { fn drop( &mut self ) { unsafe{ COUNT += 1; }}}

impl From<&'static str> for Name {
    fn from( s: &'static str ) -> Self {
        Name{ index: <Self as Indexed>::null(), text: s.to_string() }
    }
}

{
    let mut pool = Pool::<Name>::new_unmanaged();
    pool.push( "foo".into() );
    pool.push( "bar".into() );
    pool.push( "baz".into() );
}
assert_eq!( unsafe{ COUNT }, 0 );

pub fn push(&mut self, value: T)[src]

Appends an element to the back of a pool.

Panics

Panics if the number of elements in the vector overflows a usize.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: i32 }}

let mut pool = Pool::new();

pool.push( Foo::from( 0 ));
pool.push( Foo::from( 1 ));
pool.push( Foo::from( 2 ));

assert_eq!( pool.iter().map( |e| e.inner ).collect::<Vec<_>>(), vec![ 0, 1, 2 ]);

pub unsafe fn write(&mut self, index: usize, value: T)[src]

Overwrites a new value into a pool at given index without reading or dropping the old value.

Safety

This operation is marked unsafe because it accepts an index as an offset which acts like a raw pointer.

It does not drop the contents of the existing self[index] element. This is safe, but it could leak allocations or resources, so care must be taken not to overwrite an object that should be dropped.

Additionally, it does not drop value. Semantically, value is moved into self[index].

This is appropriate for initializing uninitialized memory.

Examples

Basic usage:

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: &'static str }}

let mut pool = Pool::<Foo>::new();

pool.reserve( 3 );

unsafe {
    pool.write( 0, "a".into() );
    pool.write( 2, "c".into() );
    pool.write( 1, "b".into() );
    pool.set_len( 3 );
}

assert_eq!( pool.iter().map( |e| e.inner ).collect::<Vec<_>>(), vec![ "a", "b", "c" ]);

pub fn reserve(&mut self, additional: usize)[src]

Reserves capacity for at least additional more elements to be inserted in the given Pool. The collection may reserve more space because the increasing size must be multiple of underlying chunk_len(). After calling reserve, capacity will be greater than or equal to self.new_index() + additional. Does nothing if capacity is already sufficient.

Panics

Panics if the new capacity overflows usize.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: &'static str }}

let mut pool = Pool::<Foo>::new();

pool.reserve( 0 );
assert_eq!( pool.capacity(), 0 );

pool.reserve( 1 );
let cap = pool.capacity();
assert!( cap >= 1 );

pool.reserve( 1 );
assert_eq!( pool.capacity(), cap );

pool.reserve( 1024 );
assert!( pool.capacity() >= 1024 );

pub fn len(&self) -> usize[src]

Returns the number of elements in the pool, also referred to as its ‘length’.

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: &'static str }}

let mut pool = pool!( Foo[ "a", "b", "c" ]);
assert_eq!( pool.len(), 3 );

pub unsafe fn set_len(&mut self, len: usize)[src]

Sets the length of a pool.

This will explicitly set the size of the pool, without actually modifying its buffers, so it is up to the caller to ensure that the pool is actually the specified size.

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: char }}

let mut pool = pool!( Foo[ 'r', 'u', 's', 't' ]);

unsafe {
    std::ptr::drop_in_place( &mut pool[3] );
    pool.set_len( 3 );
}

assert_eq!( pool.len(), 3 );
assert_eq!( pool.iter().map( |e| e.inner ).collect::<Vec<_>>(), vec!['r', 'u', 's'] );

In this example, there is a memory leak since the memory locations owned by the first Name were not freed prior to the set_len call:

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

static mut COUNT: usize = 0;

struct Name { index: usize, text: String }

impl_indexed!{ Name{ index: usize }}

impl Drop for Name { fn drop( &mut self ) { unsafe{ COUNT += 1; }}}

impl From<&'static str> for Name {
    fn from( s: &'static str ) -> Self {
        Name{ index: <Self as Indexed>::null(), text: s.to_string() }
    }
}

let mut pool = pool!( Name[ "abc", "def", "g" ]);

unsafe {
    std::ptr::drop_in_place( &mut pool[2] );
    std::ptr::drop_in_place( &mut pool[1] );
    pool.set_len( 0 );
}

assert_eq!( unsafe{ COUNT }, 2 );

In this example, the pool gets expanded from zero to four items without any memory allocations occurring, resulting in pool values of unallocated memory:

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: &'static str }}

let mut pool = Pool::<Foo>::new();
unsafe { pool.set_len( 3 ); }

pub fn capacity(&self) -> usize[src]

Returns the number of elements the vector can hold without more allocating.

Note: the purpose of this method is not to avoid reallocation, which could not happen at all, but to grow the buffer for next incomming write()s.

pub fn non_null(&self) -> NonNull<Self>[src]

Returns the pool’s NonNull pointer.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: i32 }}

let mut pool = Pool::<Foo>::new();
let p = pool.non_null();

assert_eq!( p, std::ptr::NonNull::new( Box::into_raw( pool )).unwrap() );

pub fn pool(value: &T) -> &Self[src]

Obtains reference of the pool of an element.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: usize }}

let mut pool = Pool::<Foo>::new();

for i in 0..1024 {
    pool.push( i.into() );
}

for i in 0..1024 {
    assert!( pool.non_null().as_ptr() as *const Pool<Foo> == pool[i].pool() );
}

pub unsafe fn pool_mut(value: &T) -> &mut Self[src]

Obtains mutable reference of the pool from an element.

Safety

This operation is marked unsafe because it obtains a mutable reference of the Pool from one of its immutable element, which may violate the memory safety rule “only one mutable reference, or none but multiple immutable references”.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: usize }}

let mut pool = Pool::<Foo>::new();

for i in 0..1024 {
    pool.push( i.into() );
}

for i in 0..1024 {
    assert_eq!( pool.non_null().as_ptr(),
                unsafe{ pool[i].pool_mut() as *mut Pool<Foo>});
}

pub fn pool_non_null(value: &T) -> NonNull<Self>[src]

Obtains NonNull pointer of the pool from an element.

pub fn new_index(&self) -> usize[src]

Returns the expected index for the next new element to be push()ed in.

pub fn is_empty(&self) -> bool[src]

Returns true if the pool contains no elements.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: &'static str }}

let mut pool = Pool::new();
assert!( pool.is_empty() );

pool.push( Foo::from( "foo" ));
assert!( !pool.is_empty() );

pub fn iter(&self) -> Iter<'_, T>

Notable traits for Iter<'a, T>

impl<'a, T: 'a + Indexed> Iterator for Iter<'a, T> type Item = &'a T;
[src]

Returns an iterator over the pool.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: &'static str }}

let mut pool = pool!( Foo[ "abc", "def", "g" ]);
let mut iter = pool.iter();

assert_eq!( iter.next().unwrap().inner, "abc" );
assert_eq!( iter.next().unwrap().inner, "def" );
assert_eq!( iter.next().unwrap().inner, "g"   );
assert!( iter.next().is_none() );

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Notable traits for IterMut<'a, T>

impl<'a, T: 'a + Indexed> Iterator for IterMut<'a, T> type Item = &'a mut T;
[src]

Returns an iterator that allows modifying each value.

Examples

#[macro_use] extern crate indexed;
use indexed::{Indexed,Pool};

extrusive_indexed!{ Foo{ inner: i32 }}

let mut pool = pool!( Foo[ 0, 1, 2 ]);

pool.iter_mut().for_each( |elem| { elem.inner += 10; });

assert_eq!( pool.iter().map( |e| e.inner ).collect::<Vec<_>>(), vec![ 10, 11, 12 ]);

pub unsafe fn get_unchecked(&self, index: usize) -> &T[src]

Returns a shared reference to the output at indexed location, without performing any bounds checking.

pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T[src]

Returns a mutable reference to the output at indexed location, without performing any bounds checking.

Trait Implementations

impl<T: Debug + Indexed> Debug for Pool<T>[src]

impl<T: Indexed> Drop for Pool<T>[src]

impl<T: Eq + Indexed> Eq for Pool<T>[src]

impl<T: Indexed> Index<usize> for Pool<T>[src]

type Output = T

The returned type after indexing.

impl<T: Indexed> IndexMut<usize> for Pool<T>[src]

impl<T: PartialEq + Indexed> PartialEq<Pool<T>> for Pool<T>[src]

impl<T: Indexed> StructuralEq for Pool<T>[src]

impl<T: Indexed> StructuralPartialEq for Pool<T>[src]

Auto Trait Implementations

impl<T> RefUnwindSafe for Pool<T> where
    T: RefUnwindSafe

impl<T> !Send for Pool<T>

impl<T> !Sync for Pool<T>

impl<T> Unpin for Pool<T> where
    T: Unpin

impl<T> UnwindSafe for Pool<T> where
    T: RefUnwindSafe + UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.