cpp_like_new/
lib.rs

1use std::{alloc::{Layout,self}, ptr::null_mut};
2
3/// Create a single object of the specified type
4pub 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}
10/// Destroy the specified object created by new_obj
11pub unsafe fn delete_obj<T>(ptr:* const T){
12	let layout = Layout::new::<T>();
13	alloc::dealloc(ptr as * mut u8, layout);
14}
15/// Return type of new_arr
16pub 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
52/// Create an array object of the specified type
53pub 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}
77/// Destroy the specified object created by new_arr
78pub 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		// i32 [e] [2] [3]
116		//type T = [[i32;3];2];
117		{
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}