use std::{ops::Index, ptr::NonNull, slice::SliceIndex}; #[repr(C)] #[derive(Debug)] pub struct TArray { data: Option>, count: u32, max: u32, } unsafe impl Send for TArray where T: Send {} unsafe impl Sync for TArray where T: Sync {} pub type FString = TArray; impl ToString for FString { fn to_string(&self) -> String { widestring::U16CStr::from_slice(&self) .expect("invalid utf16 string") .to_string_lossy() } } impl TArray { pub fn len(&self) -> usize { self.count as usize } pub fn capacity(&self) -> usize { self.max as usize } pub fn as_slice(&self) -> &[T] { match self.data { Some(ptr) => unsafe { core::slice::from_raw_parts(ptr.as_ptr(), self.len()) }, None => unsafe { core::slice::from_raw_parts(NonNull::dangling().as_ptr(), 0) }, } } pub fn as_slice_mut(&mut self) -> &mut [T] { match self.data { Some(ptr) => unsafe { core::slice::from_raw_parts_mut(ptr.as_ptr(), self.len()) }, None => unsafe { core::slice::from_raw_parts_mut(NonNull::dangling().as_ptr(), 0) }, } } } impl> Index for TArray { type Output = I::Output; fn index(&self, i: I) -> &Self::Output { let data = self.as_slice(); &data[i] } } impl std::ops::Deref for TArray { type Target = [T]; fn deref(&self) -> &Self::Target { self.as_slice() } } pub struct IntoIter { //array_ref: &'a TArray, ptr: *const T, end: *const T, } impl<'a, T> IntoIter { pub fn new(array: &'a TArray) -> Self { let ptr = array.data.unwrap().as_ptr(); Self { ptr, end: unsafe { ptr.offset(array.count as isize) }, } } } impl<'a, T> Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { if self.ptr == self.end { None } else { let old = self.ptr; self.ptr = unsafe { self.ptr.offset(1) }; Some(unsafe { std::ptr::read(old) }) } } } impl<'a, T> IntoIterator for &'a TArray { type Item = T; type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter::new(self) } }