Struct maskerad_stack_allocator::DoubleEndedAllocator [] [src]

pub struct DoubleEndedAllocator { /* fields omitted */ }

A double-ended stack-based allocator.

It uses a RawVec to allocate bytes in a vector-like fashion and two pointers: One pointing to the bottom of the stack, the other to the top of the stack.

When instantiated, one pointer is at the bottom of the stack, the other at the top of the stack.

When an object is allocated in memory, a pointer to the current top of the stack is returned and a pointer, depending from which end the object was allocated, to the current top of the stack is moved according to an offset.

This offset is calculated by the size of the object, its memory-alignment and an offset to align the object in memory.

When the allocator is reset, a pointer, depending from which end was reset, to the top of the stack is moved to its bottom of the stack. Allocation will occur from its bottom of the stack and will override previously allocated memory.

Be careful

This allocator is dropless: memory is never really freed. You must guarantee that, when overriding memory, this memory was not used.

Example

#![feature(alloc)]
use maskerad_stack_allocator::DoubleEndedAllocator;

struct Monster {
    hp :u32,
    level: u32,
}

impl Default for Monster {
    fn default() -> Self {
        Monster {
        hp: 1,
        level: 1,
        }
    }
}

//This allocator is like the StackAllocator, but the operations can be applied from the
//bottom AND the top of the stack.

//Bear in mind that if you allocated 100 bytes, you can allocate up to 50 bytes from the bottom and up to 50 bytes from the top.

let allocator = DoubleEndedAllocator::with_capacity(100); //100 bytes

//get a pointer to the top of the stack
let top_of_stack = allocator.marker_top();

//We can allocate from both sides.
let a_monster = allocator.alloc_bottom(Monster::default());
let another_monster = allocator.alloc_top(Monster::default());

//We can get pointers to the current top of the stack, from both sides.
let current_ptr_bottom = allocator.marker_bottom();
let current_ptr_top = allocator.marker_top();

assert_ne!(top_of_stack, current_ptr_top);
assert_ne!(allocator.stack().ptr(), current_ptr_bottom);

//we can reset the pointers, from both sides.
allocator.reset_top();
allocator.reset_bottom();

let current_ptr_bottom = allocator.marker_bottom();
let current_ptr_top = allocator.marker_top();

assert_eq!(top_of_stack, current_ptr_top);
assert_eq!(allocator.stack().ptr(), current_ptr_bottom);

Methods

impl DoubleEndedAllocator
[src]

[src]

Create a DoubleEndedAllocator with the given capacity (in bytes).

Example

#![feature(alloc)]
use maskerad_stack_allocator::DoubleEndedAllocator;

let allocator = DoubleEndedAllocator::with_capacity(100);
assert_eq!(allocator.stack().cap(), 100);

[src]

Return an immutable reference to the stack used by the allocator.

[src]

Move the pointer from the current top of the stack to the bottom of the stack (pointer allocating from the bottom).

Example

#![feature(alloc)]
use maskerad_stack_allocator::DoubleEndedAllocator;

let allocator = DoubleEndedAllocator::with_capacity(100);
let an_i32 = allocator.alloc_bottom(25);
let ptr_top_stack = allocator.marker_bottom();

assert_ne!(allocator.stack().ptr(), ptr_top_stack);

allocator.reset_bottom();
let ptr_top_stack = allocator.marker_bottom();
assert_eq!(allocator.stack().ptr(), ptr_top_stack);

[src]

Move the pointer from the current top of the stack to the bottom of the stack (pointer allocating from the top).

Example

#![feature(alloc)]
use maskerad_stack_allocator::DoubleEndedAllocator;

let allocator = DoubleEndedAllocator::with_capacity(100);

//get a ptr to the top of the stack
let top_stack = allocator.marker_top();

let an_i32 = allocator.alloc_top(25);
let ptr_top_stack = allocator.marker_top();

assert_ne!(top_stack, ptr_top_stack);

allocator.reset_top();
let ptr_top_stack = allocator.marker_top();
assert_eq!(top_stack, ptr_top_stack);

[src]

Allocate data in the allocator's memory, from the current top of the stack (pointer allocating from the bottom).

Panics

This function will panic if the current length of the allocator + the size of the allocated object exceed the allocator's capacity divided by 2.

Example

use maskerad_stack_allocator::DoubleEndedAllocator;

let allocator = DoubleEndedAllocator::with_capacity(100);

let my_i32 = allocator.alloc_bottom(26);
assert_eq!(my_i32, &mut 26);

[src]

Allocate data in the allocator's memory, from the current top of the stack (pointer allocating from the top).

Panics

This function will panic if the current length of the allocator + the size of the allocated object exceed the allocator's capacity divided by 2.

Example

use maskerad_stack_allocator::DoubleEndedAllocator;

let allocator = DoubleEndedAllocator::with_capacity(100);

let my_i32 = allocator.alloc_top(26);
assert_eq!(my_i32, &mut 26);

[src]

Return a pointer to the current top of the stack (pointer allocating from the top).

[src]

Return a pointer to the current top of the stack (pointer allocating from the bottom).

Example

#![feature(alloc)]
use maskerad_stack_allocator::DoubleEndedAllocator;

let allocator = DoubleEndedAllocator::with_capacity(100);
let ptr_bottom_stack = allocator.marker_bottom();

// allocator.stack().ptr() return a pointer to the start of the allocation (the bottom of the stack).
// Nothing has been allocated on the stack, the top of the stack is at the bottom.
assert_eq!(allocator.stack().ptr(), ptr_bottom_stack);

[src]

Move the pointer from the current top of the stack to a marker (pointer allocating from the top).

Example

#![feature(alloc)]
use maskerad_stack_allocator::DoubleEndedAllocator;

let allocator = DoubleEndedAllocator::with_capacity(100);
let ptr_top = allocator.marker_top(); // bottom of the stack.

let an_i32 = allocator.alloc_top(25);
// top of the stack after one allocation.
let ptr_one_alloc = allocator.marker_top();
assert_ne!(ptr_top, ptr_one_alloc);

// The current top of the stack is now at the bottom.
allocator.reset_to_marker_top(ptr_top);
let new_ptr_top = allocator.marker_top();
assert_eq!(ptr_top, new_ptr_top);

[src]

Move the pointer from the current top of the stack to a marker (pointer allocating from the bottom).

Example

#![feature(alloc)]
use maskerad_stack_allocator::DoubleEndedAllocator;

let allocator = DoubleEndedAllocator::with_capacity(100);
let ptr_bottom = allocator.marker_bottom(); // bottom of the stack.
assert_eq!(allocator.stack().ptr(), ptr_bottom);

let an_i32 = allocator.alloc_bottom(25);
// top of the stack after one allocation.
let ptr_one_alloc = allocator.marker_bottom();
assert_ne!(allocator.stack().ptr(), ptr_one_alloc);

// The current top of the stack is now at the bottom.
allocator.reset_to_marker_bottom(ptr_bottom);
let ptr_bottom = allocator.marker_bottom();
assert_eq!(allocator.stack().ptr(), ptr_bottom);