diff --git a/src/bin/example.rs b/src/bin/example.rs
index e470ac0..c68858f 100644
@@ -16,6 +16,7 @@ use alloc_no_stdlib::SliceWrapperMut;
use alloc_no_stdlib::AllocatedStackMemory;
use alloc_no_stdlib::Allocator;
use alloc_no_stdlib::StackAllocator;
+use alloc_no_stdlib::Initializer;
declare_stack_allocator_struct!(CallocAllocatedFreelist4, 4, calloc);
declare_stack_allocator_struct!(StackAllocatedFreelist16, 16, stack);
declare_stack_allocator_struct!(BoxAllocatedFreelist, heap);
diff --git a/src/init.rs b/src/init.rs
index 36f15d9..7d4da46 100644
@@ -40,7 +40,7 @@ macro_rules! static_array {
#[macro_export]
macro_rules! define_stack_allocator_traits(
($name : ident, global) => {
- impl<'a, T: 'a> Default for $name<'a, T> {
+ impl<'a, T: 'a, I : Initializer<T> + Default> Default for $name<'a, T, I> {
fn default() -> Self {
return $name::<'a, T>{freelist : &mut[],};
}
@@ -48,7 +48,7 @@ macro_rules! define_stack_allocator_traits(
define_stack_allocator_traits!($name, generic);
};
($name : ident, $freelist_size : tt, stack) => {
- impl<'a, T: 'a> Default for $name<'a, T> {
+ impl<'a, T: 'a, I : Initializer<T> + Default> Default for $name<'a, T, I> {
fn default() -> Self {
return $name::<'a, T>{freelist : static_array!(&mut[]; $freelist_size)};
}
@@ -56,7 +56,7 @@ macro_rules! define_stack_allocator_traits(
define_stack_allocator_traits!($name, generic);
};
($name : ident, heap) => {
- impl<'a, T: 'a> Default for $name<'a, T> {
+ impl<'a, T: 'a, I : Initializer<T> + Default> Default for $name<'a, T, I> {
fn default() -> Self {
let v : Vec<&mut [T]> = Vec::new();
let b = v.into_boxed_slice();
@@ -66,7 +66,7 @@ macro_rules! define_stack_allocator_traits(
define_stack_allocator_traits!($name, generic);
};
($name : ident, $freelist_size : tt, calloc) => {
- impl<'a, T: 'a> Default for $name<'a, T> {
+ impl<'a, T: 'a, I : Initializer<T> + Default> Default for $name<'a, T, I> {
fn default() -> Self {
return $name::<'a, T>{freelist : static_array!(&mut[]; $freelist_size)};
}
@@ -74,24 +74,24 @@ macro_rules! define_stack_allocator_traits(
define_stack_allocator_traits!($name, generic);
};
($name : ident, generic) => {
- impl<'a, T: 'a> SliceWrapper<&'a mut[T]> for $name<'a, T> {
+ impl<'a, T: 'a, I : Initializer<T> + Default> SliceWrapper<&'a mut[T]> for $name<'a, T, I> {
fn slice(& self) -> & [&'a mut[T]] {
return & self.freelist;
}
}
- impl<'a, T: 'a> SliceWrapperMut<&'a mut [T]> for $name<'a, T> {
+ impl<'a, T: 'a, I : Initializer<T> + Default> SliceWrapperMut<&'a mut [T]> for $name<'a, T, I> {
fn slice_mut(& mut self) ->&mut [&'a mut [T]] {
return &mut self.freelist;
}
}
- impl<'a, T: 'a> ops::Index<usize> for $name<'a, T> {
+ impl<'a, T: 'a, I : Initializer<T> + Default> ops::Index<usize> for $name<'a, T, I> {
type Output = [T];
fn index<'b> (&'b self, _index : usize) -> &'b [T] {
return &self.freelist[_index];
}
}
- impl<'a, T: 'a> ops::IndexMut<usize> for $name<'a, T> {
+ impl<'a, T: 'a, I : Initializer<T> + Default> ops::IndexMut<usize> for $name<'a, T, I> {
fn index_mut<'b>(&'b mut self, _index : usize) -> &'b mut [T] {
return &mut self.freelist[_index];
}
@@ -103,13 +103,14 @@ macro_rules! define_stack_allocator_traits(
macro_rules! declare_stack_allocator_struct(
(@as_expr $expr : expr) => {$expr};
(@new_method $name : ident, $freelist_size : tt) => {
- impl<'a, T: 'a> $name<'a, T> {
- fn new_allocator(global_buffer : &'a mut [T]) -> StackAllocator<'a, T, $name<'a, T> > {
- let mut retval = StackAllocator::<T, $name<T> > {
+ impl<'a, T: 'a, I : Initializer<T> + Default> $name<'a, T, I> {
+ fn new_allocator(global_buffer : &'a mut [T]) -> StackAllocator<'a, T, $name<'a, T>, I > {
+ let mut retval = StackAllocator::<T, $name<T>, I > {
nop : &mut [],
system_resources : $name::<T>::default(),
free_list_start : declare_stack_allocator_struct!(@as_expr $freelist_size),
free_list_overflow_count : 0,
+ initializer : I::default(),
};
retval.free_cell(AllocatedStackMemory::<T>{mem:global_buffer});
return retval;
@@ -223,14 +224,15 @@ macro_rules! initialize_allocator(
(@as_expr $expr:expr) => {$expr};
- ($name : ident, $freelist_size : tt, $T : ty, calloc) => {
- StackAllocator::<$T, $name<$T> > {
+ ($name : ident, $freelist_size : tt, $T : ty, $Initializer : expr, calloc) => {
+ StackAllocator::<$T, $name<$T> , $Initializer> {
nop : &mut [],
system_resources : $name::<$T> {
freelist : static_array!(&mut[]; $freelist_size),
},
free_list_start : $freelist_size,
free_list_overflow_count : 0,
+ initializer : $Initializer::default(),
}
};
);
diff --git a/src/lib.rs b/src/lib.rs
index 686489c..ae126ec 100644
@@ -14,4 +14,5 @@ pub use allocated_memory::AllocatedSlice;
pub use allocated_stack_memory::AllocatedStackMemory;
pub use stack_allocator::Allocator;
pub use stack_allocator::StackAllocator;
+pub use stack_allocator::Initializer;
diff --git a/src/stack_allocator.rs b/src/stack_allocator.rs
index 66e00fc..18d50cc 100644
@@ -10,21 +10,35 @@ pub trait Allocator<T> {
}
+pub trait Initializer<T> {
+ fn initialize(&mut self, &mut [T]);
+}
pub struct StackAllocator<'a,
T :'a,
- U : allocated_memory::AllocatedSlice<&'a mut [T]> > {
+ U : allocated_memory::AllocatedSlice<&'a mut [T]>,
+ I : Initializer<T> + Default, > {
pub nop : &'a mut [T],
pub system_resources : U,
pub free_list_start : usize,
pub free_list_overflow_count : usize,
+ pub initializer : I,
}
-
-impl<'a, T : 'a, U : allocated_memory::AllocatedSlice<&'a mut[T]> >
- Allocator<T> for StackAllocator <'a, T, U> {
+impl <'a, T : 'a, U : allocated_memory::AllocatedSlice<&'a mut[T]>, I : Initializer<T> + Default >
+ StackAllocator <'a, T, U, I> {
+ pub fn clear_if_necessary(self : &mut Self, index : usize, data : AllocatedStackMemory<'a, T>)
+ -> AllocatedStackMemory<'a, T> {
+ if index + 1 != self.system_resources.slice().len() {
+ self.initializer.initialize(data.mem);
+ }
+ return data;
+ }
+}
+impl<'a, T : 'a, U : allocated_memory::AllocatedSlice<&'a mut[T]>, I : Initializer<T> + Default>
+ Allocator<T> for StackAllocator <'a, T, U, I> {
type AllocatedMemory = AllocatedStackMemory<'a, T>;
- fn alloc_cell(self : &mut StackAllocator<'a, T, U>,
+ fn alloc_cell(self : &mut StackAllocator<'a, T, U, I>,
len : usize) -> AllocatedStackMemory<'a, T> {
if len == 0 {
return AllocatedStackMemory::<'a, T>::default();
@@ -57,14 +71,15 @@ impl<'a, T : 'a, U : allocated_memory::AllocatedSlice<&'a mut[T]> >
farthest_free_list);
}
self.free_list_start += 1;
- return AllocatedStackMemory::<'a, T>{mem:available_slice};
+ return self.clear_if_necessary(index,
+ AllocatedStackMemory::<'a, T>{mem:available_slice});
} else { // the memory allocated was not the entire range of items. Split and move on
let (mut retval, return_to_sender) = available_slice.split_at_mut(len);
core::mem::replace(&mut self.system_resources.slice_mut()[index], return_to_sender);
- return AllocatedStackMemory::<'a, T>{mem:retval};
+ return self.clear_if_necessary(index, AllocatedStackMemory::<'a, T>{mem:retval});
}
}
- fn free_cell(self : &mut StackAllocator<'a, T, U>,
+ fn free_cell(self : &mut StackAllocator<'a, T, U, I>,
mut val : AllocatedStackMemory<'a, T>) {
if val.slice().len() == 0 {
return;