eta_algorithms/data_structs/array/
mod.rs1use std::alloc::{realloc, Layout};
2use std::cmp::min;
3use std::marker::PhantomData;
4use std::ops::{Index, IndexMut};
5use std::ptr;
6use std::ptr::{addr_of_mut, copy_nonoverlapping};
7
8pub mod iterator;
9
10pub struct Array<T>
11where
12 T: Copy + Sized,
13{
14 phantom_data: PhantomData<()>, layout: Layout,
16 data: *mut T,
17 capacity: usize,
18}
19
20impl<T> Clone for Array<T>
21where
22 T: Copy + Sized,
23{
24 fn clone(&self) -> Self {
25 let array = Self::new(self.capacity);
26 unsafe { copy_nonoverlapping(self.data, array.data, self.capacity) }
27 array
28 }
29}
30
31impl<T> Array<T>
32where
33 T: Copy + Sized,
34{
35 #[inline(always)]
36 pub fn capacity(&self) -> usize {
37 self.capacity
38 }
39 pub fn resize(&mut self, new_capacity: usize) {
40 let new_layout = Layout::array::<T>(new_capacity).expect("Failed to create layout");
41 let new_ptr = unsafe { realloc(self.data as *mut u8, new_layout, new_layout.size()) };
42 if new_ptr.is_null() {
43 panic!("Failed to allocate memory");
44 }
45 self.data = new_ptr as *mut T;
46 self.capacity = new_capacity;
47 self.layout = new_layout;
48 }
49 #[inline(always)]
50 pub fn resize_by(&mut self, additional_capacity: usize) {
51 self.resize(self.capacity + additional_capacity);
52 }
53
54 pub fn as_ptr(&self) -> *const T {
55 self.data
56 }
57
58 pub fn as_mut_ptr(&mut self) -> *mut T {
59 self.data
60 }
61
62 pub fn new(capacity: usize) -> Self {
63 let layout = Layout::array::<T>(capacity).expect("Failed to create layout");
64 let data = unsafe { std::alloc::alloc(layout) as *mut T };
65 if data.is_null() {
66 panic!("Failed to allocate memory");
67 }
68 Array {
69 phantom_data: PhantomData,
70 layout,
71 data,
72 capacity,
73 }
74 }
75
76 #[inline(always)]
77 pub fn new_default_bytes(capacity: usize, default: u8) -> Self {
78 let arr = Self::new(capacity);
79 unsafe { ptr::write_bytes(arr.data, default, capacity) };
80 arr
81 }
82 #[inline(always)]
83 pub fn new_with_default(capacity: usize, default: T) -> Self
84 where
85 T: Copy,
86 {
87 let mut arr = Self::new(capacity);
88 arr.fill(default);
89 arr
90 }
91
92 pub fn fill(&mut self, value: T)
93 where
94 T: Copy,
95 {
96 for i in self.iter_mut() {
97 *i = value;
98 }
99 }
100 #[inline(always)]
101 pub fn iter(&self) -> iterator::ArrayIterator<T> {
102 iterator::ArrayIterator {
103 phantom_data: &self.phantom_data,
104 data: self.data,
105 end: unsafe { self.data.add(self.capacity) },
106 }
107 }
108
109 #[inline(always)]
110 pub fn iter_mut(&mut self) -> iterator::ArrayIteratorMut<T> {
111 iterator::ArrayIteratorMut {
112 phantom_data: &mut self.phantom_data,
113 data: self.data,
114 end: unsafe { self.data.add(self.capacity) },
115 }
116 }
117
118 #[inline(always)]
119 pub fn iter_range(&self, start: usize, end: usize) -> iterator::ArrayIterator<T> {
120 iterator::ArrayIterator {
121 phantom_data: &self.phantom_data,
122 data: unsafe { self.data.add(start) },
123 end: unsafe { min(self.data.add(end), self.data.add(self.capacity)) },
124 }
125 }
126
127 #[inline(always)]
128 pub fn iter_range_mut(&mut self, start: usize, end: usize) -> iterator::ArrayIteratorMut<T> {
129 iterator::ArrayIteratorMut {
130 phantom_data: &mut self.phantom_data,
131 data: unsafe { self.data.add(start) },
132 end: unsafe { min(self.data.add(end), self.data.add(self.capacity)) },
133 }
134 }
135
136 #[inline(always)]
139 pub unsafe fn iter_range_mut_unchecked(&mut self, start: usize, end: usize) -> iterator::ArrayIteratorMut<'static, T> {
140 static mut PHANTOM: PhantomData<()> = PhantomData;
141 iterator::ArrayIteratorMut {
142 phantom_data: &mut *addr_of_mut!(PHANTOM),
143 data: unsafe { self.data.add(start) },
144 end: unsafe { min(self.data.add(end), self.data.add(self.capacity)) },
145 }
146 }
147
148 pub fn from_vec(vec: Vec<T>) -> Self {
150 let arr = Self::new(vec.len());
151 unsafe {
152 copy_nonoverlapping(vec.as_ptr(), arr.data, arr.capacity);
153 arr
154 }
155 }
156 pub fn from_slice(slice: &[T]) -> Self {
158 let arr = Self::new(slice.len());
159 unsafe {
160 copy_nonoverlapping(slice.as_ptr(), arr.data, arr.capacity);
161 arr
162 }
163 }
164
165 pub fn as_slice(&self) -> &[T] {
166 unsafe { std::slice::from_raw_parts(self.data, self.capacity) }
167 }
168
169 pub fn as_mut_slice(&mut self) -> &mut [T] {
170 unsafe { std::slice::from_raw_parts_mut(self.data, self.capacity) }
171 }
172
173 pub fn split_at(&mut self, index: usize) -> (&[T], &[T]) {
174 if index >= self.capacity {
175 panic!("Index out of bounds");
176 }
177 let new_data = unsafe { self.data.add(index) };
178 let left = unsafe { std::slice::from_raw_parts(self.data, index) };
179 let right = unsafe { std::slice::from_raw_parts(new_data, self.capacity - index) };
180 (left, right)
181 }
182
183 pub fn split_at_mut(&mut self, index: usize) -> (&mut [T], &mut [T]) {
184 if index >= self.capacity {
185 panic!("Index out of bounds");
186 }
187 let new_data = unsafe { self.data.add(index) };
188 let left = unsafe { std::slice::from_raw_parts_mut(self.data, index) };
189 let right = unsafe { std::slice::from_raw_parts_mut(new_data, self.capacity - index) };
190 (left, right)
191 }
192
193 pub fn split_into_parts(&self, parts: usize) -> Array<&[T]> {
194 if parts > self.capacity {
195 panic!("Parts must be less than or equal to the capacity of the array");
196 }
197
198 if parts == 0 {
199 panic!("Parts cannot be 0");
200 }
201
202 let chunk_size = self.capacity / parts;
203 let remainder = self.capacity % parts;
204
205 let mut arr = Array::<&[T]>::new(parts);
206 let mut ptr = self.data as *const T;
207 for i in 0..parts - 1 {
208 arr[i] = unsafe { std::slice::from_raw_parts(ptr, chunk_size) };
209 ptr = unsafe { ptr.add(chunk_size) };
210 }
211
212 arr[parts - 1] = unsafe { std::slice::from_raw_parts(ptr, chunk_size + remainder) };
213
214 arr
215 }
216 pub fn split_into_parts_mut(&mut self, parts: usize) -> Vec<&mut [T]> {
217 if parts >= self.capacity {
218 panic!("Parts must be less than or equal to the capacity of the array");
219 }
220
221 if parts == 0 {
222 panic!("Parts cannot be 0");
223 }
224
225 let chunk_size = self.capacity / parts;
226 let remainder = self.capacity % parts;
227
228 let mut arr = Vec::<&mut [T]>::with_capacity(parts);
229 let mut ptr = self.data;
230 for _ in 0..parts - 1 {
231 arr.push(unsafe { std::slice::from_raw_parts_mut(ptr, chunk_size) });
232 ptr = unsafe { ptr.add(chunk_size) };
233 }
234
235 arr.push(unsafe { std::slice::from_raw_parts_mut(ptr, chunk_size + remainder) });
236 arr
237 }
238 #[inline(always)]
239 pub unsafe fn index_unchecked(&self, index: usize) -> &T {
240 self.data.add(index).as_ref().unwrap()
241 }
242
243 #[inline(always)]
244 pub unsafe fn index_unchecked_mut(&mut self, index: usize) -> &mut T {
245 self.data.add(index).as_mut().unwrap()
246 }
247}
248
249impl<T> Drop for Array<T>
250where
251 T: Copy + Sized,
252{
253 fn drop(&mut self) {
254 unsafe {
255 std::alloc::dealloc(self.data as *mut u8, self.layout);
256 }
257 }
258}
259
260impl<T> Index<usize> for Array<T>
261where
262 T: Copy + Sized,
263{
264 type Output = T;
265
266 #[inline(always)]
267 fn index(&self, index: usize) -> &Self::Output {
268 if index >= self.capacity {
269 panic!("Index out of bounds");
270 }
271
272 unsafe { &*self.data.add(index) }
273 }
274}
275
276impl<T> IndexMut<usize> for Array<T>
277where
278 T: Copy + Sized,
279{
280 #[inline(always)]
281 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
282 if index >= self.capacity {
283 panic!("Index out of bounds");
284 }
285 unsafe { &mut *self.data.add(index) }
286 }
287}