algorithms_edu/data_structures/heaparray.rs
1// //! Dynamically allocated array that mimics:
2// //!
3// //! - `int[] arr = new int[size];` in Java
4// //! - `int *arr = (int *)malloc(size * sizeof(int));` in C
5
6// use std::alloc::{alloc, dealloc, Layout};
7// pub struct HeapArray<T: Clone> {
8// ptr: *mut T,
9// len: usize,
10// }
11
12// impl<T: Clone> HeapArray<T> {
13// pub fn new(len: usize) -> Self {
14// let ptr = unsafe {
15// let layout = Layout::from_size_align_unchecked(len, std::mem::size_of::<T>());
16// alloc(layout) as *mut T
17// };
18// Self { ptr, len }
19// }
20// pub fn init(len: usize, val: T) -> Self {
21// let mut arr = Self::new(len);
22// for i in 0..len {
23// unsafe {
24// *arr.get_unchecked_mut(i) = val.clone();
25// }
26// }
27// arr
28// }
29// pub fn init_with(len: usize, f: impl Fn(usize) -> T) -> Self {
30// let mut arr = Self::new(len);
31// for i in 0..len {
32// unsafe {
33// *arr.get_unchecked_mut(i) = f(i);
34// }
35// }
36// arr
37// }
38// pub fn len(&self) -> usize {
39// self.len
40// }
41// pub fn as_slice(&self) -> &[T] {
42// unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
43// }
44// pub fn as_mut_slice(&mut self) -> &mut [T] {
45// unsafe { std::slice::from_raw_parts_mut(self.ptr, self.len) }
46// }
47// }
48
49// impl<T: Clone> Drop for HeapArray<T> {
50// fn drop(&mut self) {
51// unsafe {
52// dealloc(
53// self.ptr as *mut u8,
54// Layout::from_size_align_unchecked(self.len, std::mem::size_of::<T>()),
55// )
56// };
57// }
58// }
59
60// impl<T: Clone> std::ops::Deref for HeapArray<T> {
61// type Target = [T];
62// fn deref(&self) -> &Self::Target {
63// self.as_slice()
64// }
65// }
66// impl<T: Clone> std::ops::DerefMut for HeapArray<T> {
67// fn deref_mut(&mut self) -> &mut Self::Target {
68// self.as_mut_slice()
69// }
70// }
71
72// impl<T: Clone> std::ops::Index<usize> for HeapArray<T> {
73// type Output = T;
74// fn index(&self, index: usize) -> &Self::Output {
75// self.get(index).unwrap()
76// }
77// }
78// impl<T: Clone> std::ops::Index<std::ops::Range<usize>> for HeapArray<T> {
79// type Output = [T];
80// fn index(&self, index: std::ops::Range<usize>) -> &Self::Output {
81// unsafe { std::slice::from_raw_parts(self.ptr.add(index.start), index.end - index.start) }
82// }
83// }
84// impl<T: Clone> std::ops::IndexMut<usize> for HeapArray<T> {
85// fn index_mut(&mut self, index: usize) -> &mut Self::Output {
86// self.get_mut(index).unwrap()
87// }
88// }
89// impl<T: Clone> std::ops::IndexMut<std::ops::Range<usize>> for HeapArray<T> {
90// fn index_mut(&mut self, index: std::ops::Range<usize>) -> &mut Self::Output {
91// unsafe {
92// std::slice::from_raw_parts_mut(self.ptr.add(index.start), index.end - index.start)
93// }
94// }
95// }
96
97// // #[cfg(test)]
98// // mod tests {
99// // use super::*;
100// // #[test]
101// // fn test_heaparray() {
102// // let mut arr = HeapArray::init_with(10, |x| x);
103// // assert_eq!(arr[1], 1);
104// // let slc = &mut arr[5..10];
105// // slc[2] = 100;
106// // assert_eq!(slc, &[5, 6, 100, 8, 9]);
107// // println!("{:?}", arr[9]);
108// // }
109// // }