105 lines
2.3 KiB
Rust
105 lines
2.3 KiB
Rust
use std::{ops::Index, ptr::NonNull, slice::SliceIndex};
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug)]
|
|
pub struct TArray<T> {
|
|
data: Option<NonNull<T>>,
|
|
count: u32,
|
|
max: u32,
|
|
}
|
|
|
|
unsafe impl<T> Send for TArray<T> where T: Send {}
|
|
unsafe impl<T> Sync for TArray<T> where T: Sync {}
|
|
|
|
pub type FString = TArray<u16>;
|
|
|
|
impl ToString for FString {
|
|
fn to_string(&self) -> String {
|
|
widestring::U16CStr::from_slice(&self)
|
|
.expect("invalid utf16 string")
|
|
.to_string_lossy()
|
|
}
|
|
}
|
|
|
|
impl<T> TArray<T> {
|
|
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<T, I: SliceIndex<[T]>> Index<I> for TArray<T> {
|
|
type Output = I::Output;
|
|
|
|
fn index(&self, i: I) -> &Self::Output {
|
|
let data = self.as_slice();
|
|
|
|
&data[i]
|
|
}
|
|
}
|
|
|
|
impl<T> std::ops::Deref for TArray<T> {
|
|
type Target = [T];
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
self.as_slice()
|
|
}
|
|
}
|
|
|
|
pub struct IntoIter<T> {
|
|
//array_ref: &'a TArray<T>,
|
|
ptr: *const T,
|
|
end: *const T,
|
|
}
|
|
|
|
impl<'a, T> IntoIter<T> {
|
|
pub fn new(array: &'a TArray<T>) -> Self {
|
|
let ptr = array.data.unwrap().as_ptr();
|
|
Self {
|
|
ptr,
|
|
end: unsafe { ptr.offset(array.count as isize) },
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, T> Iterator for IntoIter<T> {
|
|
type Item = T;
|
|
|
|
fn next(&mut self) -> Option<T> {
|
|
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<T> {
|
|
type Item = T;
|
|
type IntoIter = IntoIter<T>;
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
IntoIter::new(self)
|
|
}
|
|
}
|