malloc_array/
store.rs

1use crate::*;
2
3/// Statically typed pointer store. `free()`s and drops on drop.
4#[derive(Debug)]
5pub struct Store<T>
6{
7    pointers: Vec<*mut T>,
8}
9
10#[cfg(test)]
11mod tests
12{
13    use super::*;
14    #[test]
15    fn store()
16    {
17	let mut store = Store::new();
18	unsafe {
19	    for _a in 0..10 {
20		let _ptr = store.ptr(alloc::malloc(100).unwrap());
21	    }
22	}
23    }
24    #[test]
25    fn dyn_store()
26    {
27	let mut store = DynStore::new();
28	unsafe {
29	    for _a in 0..10 {
30		let ptr = store.ptr(alloc::malloc(4).unwrap() as *mut u32);
31		*ptr = 100u32;
32	    }
33	}
34	
35    }
36    #[test]
37    fn into_ha()
38    {
39	let mut store = Store::new();
40	unsafe {
41	    for a in 0..10 {
42		*store.ptr(alloc::malloc(4).unwrap() as *mut u32) = a;
43	    }
44	}
45	let ha = store.into_heap_array();
46	assert_eq!(ha.len(), 10);
47	assert_eq!(&ha[..], &[0,1,2,3,4,5,6,7,8,9]);
48    }
49}
50
51impl<T> Store<T>
52{
53    /// Create a new pointer store.
54    pub fn new() -> Self
55    {
56	Self{pointers:Vec::new()}
57    }
58
59    /// Add a pointer to the store.
60    pub fn ptr(&mut self, ptr: *mut T) -> *mut T
61    {
62	self.pointers.push(ptr);
63	ptr
64    }
65
66    /// Remove a pointer from the store.
67    pub fn remove(&mut self, ptr: *mut T)
68    {
69	while let Some(i) = self.pointers.iter().position(|x| *x == ptr)
70	{
71	    self.pointers.remove(i);
72	}
73    }
74
75    /// Consumes the instance and returns the pointers without freeing them.
76    pub fn into_raw_parts(mut self) -> Vec<*mut T>
77    {
78	std::mem::replace(&mut self.pointers, Vec::new())
79    }
80
81    /// Consume a vector of pointers and return a new `Store<T>`.
82    pub fn from_raw_parts(pointers: Vec<*mut T>) -> Self
83    {
84	Self {
85	    pointers,
86	}
87    }
88    
89    /// Free all the pointers in the store without calling their destructors (if the have any).
90    pub fn free(mut self)
91    {
92	for &mut x in self.pointers.iter_mut()
93	{
94	    unsafe {
95		alloc::free(x as VoidPointer);
96	    }
97	}
98	self.pointers.clear()
99    }
100
101    /// Move all data from all pointers into a new `HeapArray<T>` instance and free the old pointers.
102    pub fn into_heap_array(mut self) -> HeapArray<T>
103    {
104	let mut output = heap![T; self.pointers.len()];
105	for (mut init, old) in output.initialise().zip(std::mem::replace(&mut self.pointers, Vec::new()).into_iter())
106	{
107	    unsafe {
108		init.put(ptr::take(old));
109		alloc::free(old as *mut ());
110	    }
111	}
112	output
113    }
114}
115
116impl<T> std::ops::Drop for Store<T>
117{
118    fn drop(&mut self)
119    {
120	for &mut ptr in self.pointers.iter_mut()
121	{
122	    unsafe {
123		drop(ptr::take(ptr));
124		alloc::free(ptr as VoidPointer);
125	    }
126	}
127	self.pointers.clear();
128    }
129}
130
131/// Dynamically typed pointer store. Frees on drop.
132#[derive(Debug)]
133pub struct DynStore
134{
135    pointers: Vec<VoidPointer>,
136}
137
138impl DynStore
139{
140    /// Create a new pointer store.
141    pub fn new() -> Self
142    {
143	Self{pointers:Vec::new()}
144    }
145
146    /// Add a pointer to the store.
147    pub fn ptr<T>(&mut self, ptr: *mut T) -> *mut T
148    {
149	self.pointers.push(ptr as VoidPointer);
150	ptr
151    }
152
153    /// Remove a pointer from the store.
154    pub fn remove<T>(&mut self, ptr: *mut T)
155    {
156	while let Some(i) = self.pointers.iter().position(|x| *x == ptr as VoidPointer)
157	{
158	    self.pointers.remove(i);
159	}
160    }
161
162    /// Consumes the instance and returns the pointers without freeing them.
163    pub fn into_raw_parts(mut self) -> Vec<*mut ()>
164    {
165	std::mem::replace(&mut self.pointers, Vec::new())
166    }
167    
168    /// Consume a vector of pointers and return a new `Store<T>`.
169    pub fn from_raw_parts(pointers: Vec<*mut ()>) -> Self
170    {
171	Self {
172	    pointers,
173	}
174    }
175
176    
177    /// Free all the pointers in the store without calling their destructors (if the have any).
178    pub fn free(mut self)
179    {
180	for &mut x in self.pointers.iter_mut()
181	{
182	    unsafe {
183		alloc::free(x);
184	    }
185	}
186	self.pointers.clear()
187    }
188    
189}
190
191impl std::ops::Drop for DynStore
192{
193    fn drop(&mut self)
194    {
195	for &mut ptr in self.pointers.iter_mut()
196	{
197	    unsafe {
198		drop(ptr::take(ptr));
199		alloc::free(ptr);
200	    }
201	}
202	self.pointers.clear();
203    }
204}
205
206impl<T> IntoIterator for Store<T>
207{
208    type Item = *mut T;
209    type IntoIter = std::vec::IntoIter<Self::Item>;
210
211    fn into_iter(mut self) -> Self::IntoIter
212    {
213	std::mem::replace(&mut self.pointers, Vec::new()).into_iter()
214    }
215}
216
217impl IntoIterator for DynStore
218{
219    type Item = *mut ();
220    type IntoIter = std::vec::IntoIter<Self::Item>;
221
222    fn into_iter(mut self) -> Self::IntoIter
223    {
224	std::mem::replace(&mut self.pointers, Vec::new()).into_iter()
225    }
226}
227
228use std::iter::FromIterator;
229impl<T> FromIterator<*mut T> for Store<T>
230{
231    fn from_iter<I: IntoIterator<Item=*mut T>>(iter: I) -> Self
232    {
233	Self {
234	    pointers: Vec::from_iter(iter)
235	}
236    }
237}
238
239impl<T> FromIterator<*mut T> for DynStore
240{
241    fn from_iter<I: IntoIterator<Item=*mut T>>(iter: I) -> Self
242    {
243	Self {
244	    pointers: Vec::from_iter(iter.into_iter().map(|x| x as *mut ()))
245	}
246    }
247}