parent
ba1d610d3d
commit
1f0880329a
@ -0,0 +1,247 @@
|
||||
use crate::*;
|
||||
|
||||
/// Statically typed pointer store. `free()`s and drops on drop.
|
||||
#[derive(Debug)]
|
||||
pub struct Store<T>
|
||||
{
|
||||
pointers: Vec<*mut T>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests
|
||||
{
|
||||
use super::*;
|
||||
#[test]
|
||||
fn store()
|
||||
{
|
||||
let mut store = Store::new();
|
||||
unsafe {
|
||||
for _a in 0..10 {
|
||||
let _ptr = store.ptr(alloc::malloc(100).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn dyn_store()
|
||||
{
|
||||
let mut store = DynStore::new();
|
||||
unsafe {
|
||||
for _a in 0..10 {
|
||||
let ptr = store.ptr(alloc::malloc(4).unwrap() as *mut u32);
|
||||
*ptr = 100u32;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#[test]
|
||||
fn into_ha()
|
||||
{
|
||||
let mut store = Store::new();
|
||||
unsafe {
|
||||
for a in 0..10 {
|
||||
*store.ptr(alloc::malloc(4).unwrap() as *mut u32) = a;
|
||||
}
|
||||
}
|
||||
let ha = store.into_heap_array();
|
||||
assert_eq!(ha.len(), 10);
|
||||
assert_eq!(&ha[..], &[0,1,2,3,4,5,6,7,8,9]);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Store<T>
|
||||
{
|
||||
/// Create a new pointer store.
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self{pointers:Vec::new()}
|
||||
}
|
||||
|
||||
/// Add a pointer to the store.
|
||||
pub fn ptr(&mut self, ptr: *mut T) -> *mut T
|
||||
{
|
||||
self.pointers.push(ptr);
|
||||
ptr
|
||||
}
|
||||
|
||||
/// Remove a pointer from the store.
|
||||
pub fn remove(&mut self, ptr: *mut T)
|
||||
{
|
||||
while let Some(i) = self.pointers.iter().position(|x| *x == ptr)
|
||||
{
|
||||
self.pointers.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes the instance and returns the pointers without freeing them.
|
||||
pub fn into_raw_parts(mut self) -> Vec<*mut T>
|
||||
{
|
||||
std::mem::replace(&mut self.pointers, Vec::new())
|
||||
}
|
||||
|
||||
/// Consume a vector of pointers and return a new `Store<T>`.
|
||||
pub fn from_raw_parts(pointers: Vec<*mut T>) -> Self
|
||||
{
|
||||
Self {
|
||||
pointers,
|
||||
}
|
||||
}
|
||||
|
||||
/// Free all the pointers in the store without calling their destructors (if the have any).
|
||||
pub fn free(mut self)
|
||||
{
|
||||
for &mut x in self.pointers.iter_mut()
|
||||
{
|
||||
unsafe {
|
||||
alloc::free(x as VoidPointer);
|
||||
}
|
||||
}
|
||||
self.pointers.clear()
|
||||
}
|
||||
|
||||
/// Move all data from all pointers into a new `HeapArray<T>` instance and free the old pointers.
|
||||
pub fn into_heap_array(mut self) -> HeapArray<T>
|
||||
{
|
||||
let mut output = heap![T; self.pointers.len()];
|
||||
for (mut init, old) in output.initialise().zip(std::mem::replace(&mut self.pointers, Vec::new()).into_iter())
|
||||
{
|
||||
unsafe {
|
||||
init.put(ptr::take(old));
|
||||
alloc::free(old as *mut ());
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::ops::Drop for Store<T>
|
||||
{
|
||||
fn drop(&mut self)
|
||||
{
|
||||
for &mut ptr in self.pointers.iter_mut()
|
||||
{
|
||||
unsafe {
|
||||
drop(ptr::take(ptr));
|
||||
alloc::free(ptr as VoidPointer);
|
||||
}
|
||||
}
|
||||
self.pointers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// Dynamically typed pointer store. Frees on drop.
|
||||
#[derive(Debug)]
|
||||
pub struct DynStore
|
||||
{
|
||||
pointers: Vec<VoidPointer>,
|
||||
}
|
||||
|
||||
impl DynStore
|
||||
{
|
||||
/// Create a new pointer store.
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self{pointers:Vec::new()}
|
||||
}
|
||||
|
||||
/// Add a pointer to the store.
|
||||
pub fn ptr<T>(&mut self, ptr: *mut T) -> *mut T
|
||||
{
|
||||
self.pointers.push(ptr as VoidPointer);
|
||||
ptr
|
||||
}
|
||||
|
||||
/// Remove a pointer from the store.
|
||||
pub fn remove<T>(&mut self, ptr: *mut T)
|
||||
{
|
||||
while let Some(i) = self.pointers.iter().position(|x| *x == ptr as VoidPointer)
|
||||
{
|
||||
self.pointers.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes the instance and returns the pointers without freeing them.
|
||||
pub fn into_raw_parts(mut self) -> Vec<*mut ()>
|
||||
{
|
||||
std::mem::replace(&mut self.pointers, Vec::new())
|
||||
}
|
||||
|
||||
/// Consume a vector of pointers and return a new `Store<T>`.
|
||||
pub fn from_raw_parts(pointers: Vec<*mut ()>) -> Self
|
||||
{
|
||||
Self {
|
||||
pointers,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Free all the pointers in the store without calling their destructors (if the have any).
|
||||
pub fn free(mut self)
|
||||
{
|
||||
for &mut x in self.pointers.iter_mut()
|
||||
{
|
||||
unsafe {
|
||||
alloc::free(x);
|
||||
}
|
||||
}
|
||||
self.pointers.clear()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl std::ops::Drop for DynStore
|
||||
{
|
||||
fn drop(&mut self)
|
||||
{
|
||||
for &mut ptr in self.pointers.iter_mut()
|
||||
{
|
||||
unsafe {
|
||||
drop(ptr::take(ptr));
|
||||
alloc::free(ptr);
|
||||
}
|
||||
}
|
||||
self.pointers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for Store<T>
|
||||
{
|
||||
type Item = *mut T;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
fn into_iter(mut self) -> Self::IntoIter
|
||||
{
|
||||
std::mem::replace(&mut self.pointers, Vec::new()).into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for DynStore
|
||||
{
|
||||
type Item = *mut ();
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
fn into_iter(mut self) -> Self::IntoIter
|
||||
{
|
||||
std::mem::replace(&mut self.pointers, Vec::new()).into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
use std::iter::FromIterator;
|
||||
impl<T> FromIterator<*mut T> for Store<T>
|
||||
{
|
||||
fn from_iter<I: IntoIterator<Item=*mut T>>(iter: I) -> Self
|
||||
{
|
||||
Self {
|
||||
pointers: Vec::from_iter(iter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromIterator<*mut T> for DynStore
|
||||
{
|
||||
fn from_iter<I: IntoIterator<Item=*mut T>>(iter: I) -> Self
|
||||
{
|
||||
Self {
|
||||
pointers: Vec::from_iter(iter.into_iter().map(|x| x as *mut ()))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue