m6arr/
lib.rs

1#![allow(path_statements)]
2
3use core::slice;
4use std::{
5    alloc::{alloc_zeroed, Layout},
6    fmt,
7    ops::{Deref, DerefMut, Index, IndexMut},
8    ptr::{null_mut, self},
9    slice::SliceIndex, intrinsics::copy_nonoverlapping,
10};
11
12
13////////////////////////////////////////////////////////////////////////////////
14//// Structure
15
16#[repr(C)]
17pub struct Array<T> {
18    len: usize, // and capacity
19    ptr: *mut T,
20}
21
22
23////////////////////////////////////////////////////////////////////////////////
24//// Implement
25
26/// Heap Array
27impl<T> Array<T> {
28
29    ///////////////////////////////////////
30    //// static method
31
32    pub fn empty() -> Self {
33        Self::new(0)
34    }
35
36    pub fn new(cap: usize) -> Self {
37        unsafe {
38            let len = cap;
39
40            let ptr = if cap == 0 {
41                null_mut()
42            } else {
43                alloc_zeroed(Self::layout(cap)) as *mut T
44            };
45
46            Self { len, ptr }
47        }
48    }
49
50    pub fn new_with(init: T, cap: usize) -> Self
51    where
52        T: Copy,
53    {
54        unsafe {
55            let it = Self::new(cap);
56
57            for i in 0..cap {
58                (*it.ptr.add(i)) = init;
59            }
60
61            it
62        }
63    }
64
65    pub fn merge(lf: &Self, rh: &Self) -> Self {
66        let arr = Array::new(lf.len() + rh.len());
67
68        unsafe {
69            copy_nonoverlapping(lf.ptr, arr.ptr, lf.len());
70            copy_nonoverlapping(rh.ptr, arr.ptr.add(lf.len()), rh.len());
71        }
72
73        arr
74    }
75
76
77    ///////////////////////////////////////
78    //// dynamic method
79
80    pub fn len(&self) -> usize {
81        self.len
82    }
83
84    pub fn is_empty(&self) -> bool {
85        self.len == 0
86    }
87
88    pub fn layout(cap: usize) -> Layout {
89        Layout::array::<T>(cap).unwrap()
90    }
91
92    pub fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = &T> + 'a> {
93        let mut i = 0;
94
95        Box::new(std::iter::from_fn(move || {
96            if i == self.len {
97                return None;
98            }
99
100            let res = Some(&self[i]);
101            i += 1;
102
103            res
104        }))
105    }
106
107    pub fn as_ptr(&self) -> *mut T {
108        self.ptr
109    }
110
111    pub fn copy_from_slice(src: &[T]) -> Self where T: Copy {
112        let mut arr = Array::new(src.len());
113        arr[..].copy_from_slice(src);
114
115        arr
116    }
117
118
119    pub fn clone_from_slice(src: &[T]) -> Self where T: Clone {
120        let mut arr = Array::new(src.len());
121        arr[..].clone_from_slice(src);
122
123        arr
124    }
125}
126
127
128
129////////////////////////////////////////////////////////////////////////////////
130//// Standard Traits Implement
131
132impl<T> Drop for Array<T> {
133    fn drop(&mut self) {
134        unsafe {
135            // if self.len > 0 {
136            //     dealloc(self.ptr as *mut u8, Self::layout(self.len));
137            // }
138
139            ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len))
140        }
141    }
142}
143
144
145
146impl<T> Deref for Array<T> {
147    type Target = [T];
148
149    fn deref(&self) -> &[T] {
150        unsafe { slice::from_raw_parts(self.ptr, self.len) }
151    }
152}
153
154impl<T> DerefMut for Array<T> {
155    fn deref_mut(&mut self) -> &mut Self::Target {
156        unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
157    }
158}
159
160impl<T, I: SliceIndex<[T]>> Index<I> for Array<T> {
161    type Output = I::Output;
162
163    fn index(&self, index: I) -> &Self::Output {
164        Index::index(&**self, index)
165    }
166}
167
168impl<T, I: SliceIndex<[T]>> IndexMut<I> for Array<T> {
169    fn index_mut(&mut self, index: I) -> &mut Self::Output {
170        IndexMut::index_mut(&mut **self, index)
171    }
172}
173
174impl<T: Clone> Clone for Array<T> {
175    fn clone(&self) -> Self {
176        let mut cloned = Self::new(self.len);
177
178        cloned[..].clone_from_slice(&self[..]);
179
180        cloned
181    }
182}
183
184
185impl<T: Clone> From<&[T]> for Array<T> {
186    fn from(src: &[T]) -> Self {
187        let mut arr = Array::new(src.len());
188        arr[..].clone_from_slice(src);
189
190        arr
191    }
192}
193
194
195impl<T> Default for Array<T> {
196    fn default() -> Self {
197        Self::empty()
198    }
199}
200
201impl<T: fmt::Debug> fmt::Debug for Array<T> {
202    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203        fmt::Debug::fmt(&**self, f)
204    }
205}
206
207
208
209////////////////////////////////////////////////////////////////////////////////
210//// Macros
211
212#[macro_export]
213macro_rules! array {
214    ( $init:expr; $cap:expr ) => {
215        {
216            let init = $init;
217            let cap = $cap;
218
219            Array::new_with(init, cap)
220        }
221    };
222    ($($item:expr),*) => {
223        {
224            #[allow(unused_mut)]
225            let mut cnt = 0;
226            $(
227                cnt += 1;
228
229                let _ = $item;
230            )*
231
232            #[allow(unused_mut)]
233            let mut arr = Array::new(cnt);
234
235            let mut _i = 0;
236            $(
237                arr[_i] = $item;
238                _i += 1;
239            )*
240
241            arr
242        }
243    };
244
245}
246
247#[cfg(test)]
248mod tests {
249    use super::Array;
250    use crate::*;
251
252    // test from_raw_mut
253    fn f() -> Array<i32> {
254        let a = [10, 2, 4, 1];
255
256        Array::copy_from_slice(&a[..])
257    }
258
259    #[test]
260    fn test_arr() {
261        let mut arr = Array::<usize>::new(10);
262
263        arr[2] = 15;
264        arr[4] = 20;
265        println!("{}", arr[2]);
266        println!("{}", arr[1]);
267
268        let arr = [0; 0];
269
270        assert!(arr.is_empty());
271
272        let _arr2 = array![0; 3];
273        let arr2 = array!['a', 'b', 'd'];
274
275        for e in arr2.iter() {
276            println!("{}", e);
277        }
278
279        // test as_ptr/len/from_ptr
280        let _ptr = arr2.as_ptr();
281
282        let arr2 = array![1, 2, 3];
283
284        let slice0 = &arr2[..];
285
286        println!("{:?}", slice0);
287
288        println!("{:?}", arr2);
289
290        let mut arr0 = array!['a', 'c'];
291        let arr1 = array!['d', 'e'];
292
293        arr0[..].copy_from_slice(&arr1[..]);
294
295        assert_eq!(arr0[..], arr1[..]);
296
297        println!("{:?}", f())
298    }
299}
300