1use std::{alloc::{Layout,self}, ptr::null_mut};
2
3pub unsafe fn new_obj<T>(init_expr: T)-> * mut T{
5 let layout = Layout::new::<T>();
6 let raw_ptr = alloc::alloc(layout) as * mut T;
7 std::ptr::write(raw_ptr, init_expr);
8 raw_ptr
9}
10pub unsafe fn delete_obj<T>(ptr:* const T){
12 let layout = Layout::new::<T>();
13 alloc::dealloc(ptr as * mut u8, layout);
14}
15pub struct ArrayPtr<T>{
17 raw_ptr:* mut T,
18 size:usize,
19 layout:Option<Layout>
20}
21
22impl<T> ArrayPtr<T>{
23 pub fn as_slice(&self) -> Option<&[T]>{
24 self.as_mut_slice().map(|v|{
25 v as & [T]
26 })
27 }
28 pub fn as_mut_slice(&self)-> Option<& mut [T]>{
29 match self.layout{
30 Some(_)=>{
31 Some(unsafe {
32 std::slice::from_raw_parts_mut(self.raw_ptr, self.size)
33 })
34 }
35 _=>{
36 None
37 }
38 }
39 }
40 pub fn len(&self)->usize{
41 self.size
42 }
43 pub fn as_ptr(&self)-> * const T{
44 self.raw_ptr
45 }
46 pub fn as_mut_ptr(&self)->* mut T{
47 self.raw_ptr
48 }
49}
50
51
52pub unsafe fn new_arr<T:Clone + Default>(init_list:&[T], size:usize) -> ArrayPtr<T>{
54 if init_list.len() > size{
55 panic!("the number of initializer is greater than allocated size");
56 }
57 match Layout::array::<T>(size){
58 Ok(layout)=>{
59 let raw_ptr = alloc::alloc(layout.clone()) as * mut T;
60 let mut start = raw_ptr;
61 for i in init_list{
62 std::ptr::write(start, i.clone());
63 start = start.add(1);
64 }
65 let remaining_num = size - init_list.len();
66 for _ in 0.. remaining_num{
67 std::ptr::write(start, T::default());
68 start = start.add(1);
69 }
70 ArrayPtr{raw_ptr:raw_ptr,size,layout: Some(layout)}
71 }
72 Err(_)=>{
73 ArrayPtr{raw_ptr:null_mut(),size:0,layout:None}
74 }
75 }
76}
77pub unsafe fn delete_arr<T>(arr_ptr:ArrayPtr<T>){
79 match arr_ptr.layout{
80 Some(layout)=>{
81 alloc::dealloc(arr_ptr.raw_ptr as * mut u8, layout);
82 }
83 _=>{}
84 }
85}
86
87#[macro_export]
88macro_rules! form_rust_arr_declarator_from_c_arr_declarator {
89 ($type:ty, $lt0:literal, $($lt:literal), +) => {
90 [$crate::form_rust_arr_declarator_from_c_arr_declarator!($type, $($lt),+); $lt0]
91 };
92 ($type:ty, $lt:literal)=>{
93 [$type; $lt]
94 }
95}
96
97#[macro_export]
98macro_rules! new{
99 ($type:ty) => {
100 {
101 type T = $type;
102 $crate::new_obj::<$type>(T::default())
103 }
104 };
105 ($type:ty { $init:expr })=>{
106 $crate::new_obj::<$type>($init)
107 };
108 ($type:ty [ $size:expr ])=>{
109 $crate::new_arr::<$type>(&[],$size)
110 };
111 ($type:ty [ $size:expr ]{ $($init:expr),* })=>{
112 $crate::new_arr::<$type>(&[$($init),+],$size)
113 };
114 ($type:ty [$size:expr] $([$lt:literal])+)=>{
115 {
118 type T = $crate::form_rust_arr_declarator_from_c_arr_declarator!($type, $($lt),+);
119 $crate::new_arr::<T>(&[], $size)
120 }
121 };
122 ($type:ty [$size:expr] $([$lt:literal])+ { $($init:expr),* })=>{
123 {
124 type T = $crate::form_rust_arr_declarator_from_c_arr_declarator!($type, $($lt),+);
125 $crate::new_arr::<T>(&[$($init),+], $size)
126 }
127 };
128}
129
130#[macro_export]
131macro_rules! delete {
132 ($ptr:expr) => {
133 $crate::delete_obj($ptr)
134 };
135 ([] $ptr:expr)=>{
136 $crate::delete_arr($ptr)
137 };
138}
139
140#[cfg(test)]
141mod test{
142 use super::{new,delete};
143 #[test]
144 fn test_obj(){
145 unsafe{
146
147 let default_ptr = new!(i32);
148 assert_eq!(*default_ptr,0);
149 let ptr = new!(i32 {10});
150 assert_eq!(*ptr, 10);
151 delete!(default_ptr);
152 delete!(ptr);
153 };
154 }
155 #[test]
156 fn test_arr(){
157 unsafe{
158 let size = 2;
159 let ptr = new!(i32[size]);
160 assert_eq!(ptr.as_slice(),Some([0,0].as_slice()));
161 let ptr_init = new!(i32[size]{1});
162 assert_eq!(ptr_init.as_slice(),Some([1,0].as_slice()));
163 delete!([] ptr);
164 delete!([] ptr_init);
165 let multiple_arr_ptr = new!(i32[size][3]);
166 assert_eq!(multiple_arr_ptr.as_slice(),Some([[0,0,0],[0,0,0]].as_slice()));
167 let multiple_arr_ptr_init = new!(i32[size][3]{[1,2,3]});
168 assert_eq!(multiple_arr_ptr_init.as_slice(),Some([[1,2,3],[0,0,0]].as_slice()));
169 delete!([] multiple_arr_ptr);
170 delete!([] multiple_arr_ptr_init);
171 };
172 }
173}