133d722a9Sopenharmony_ci#![allow(missing_docs)] 233d722a9Sopenharmony_ci 333d722a9Sopenharmony_ciuse core::mem::{self, MaybeUninit}; 433d722a9Sopenharmony_ciuse core::ptr::{self, NonNull}; 533d722a9Sopenharmony_ciuse core::slice; 633d722a9Sopenharmony_ci 733d722a9Sopenharmony_ci// ABI compatible with C++ rust::Slice<T> (not necessarily &[T]). 833d722a9Sopenharmony_ci#[repr(C)] 933d722a9Sopenharmony_cipub struct RustSlice { 1033d722a9Sopenharmony_ci repr: [MaybeUninit<usize>; mem::size_of::<NonNull<[()]>>() / mem::size_of::<usize>()], 1133d722a9Sopenharmony_ci} 1233d722a9Sopenharmony_ci 1333d722a9Sopenharmony_ciimpl RustSlice { 1433d722a9Sopenharmony_ci pub fn from_ref<T>(slice: &[T]) -> Self { 1533d722a9Sopenharmony_ci let ptr = NonNull::from(slice).cast::<T>(); 1633d722a9Sopenharmony_ci let len = slice.len(); 1733d722a9Sopenharmony_ci Self::from_raw_parts(ptr, len) 1833d722a9Sopenharmony_ci } 1933d722a9Sopenharmony_ci 2033d722a9Sopenharmony_ci pub fn from_mut<T>(slice: &mut [T]) -> Self { 2133d722a9Sopenharmony_ci let ptr = NonNull::from(&mut *slice).cast::<T>(); 2233d722a9Sopenharmony_ci let len = slice.len(); 2333d722a9Sopenharmony_ci Self::from_raw_parts(ptr, len) 2433d722a9Sopenharmony_ci } 2533d722a9Sopenharmony_ci 2633d722a9Sopenharmony_ci pub unsafe fn as_slice<'a, T>(self) -> &'a [T] { 2733d722a9Sopenharmony_ci let ptr = self.as_non_null_ptr().as_ptr(); 2833d722a9Sopenharmony_ci let len = self.len(); 2933d722a9Sopenharmony_ci unsafe { slice::from_raw_parts(ptr, len) } 3033d722a9Sopenharmony_ci } 3133d722a9Sopenharmony_ci 3233d722a9Sopenharmony_ci pub unsafe fn as_mut_slice<'a, T>(self) -> &'a mut [T] { 3333d722a9Sopenharmony_ci let ptr = self.as_non_null_ptr().as_ptr(); 3433d722a9Sopenharmony_ci let len = self.len(); 3533d722a9Sopenharmony_ci unsafe { slice::from_raw_parts_mut(ptr, len) } 3633d722a9Sopenharmony_ci } 3733d722a9Sopenharmony_ci 3833d722a9Sopenharmony_ci pub(crate) fn from_raw_parts<T>(ptr: NonNull<T>, len: usize) -> Self { 3933d722a9Sopenharmony_ci // TODO: use NonNull::from_raw_parts(ptr.cast(), len) when stable. 4033d722a9Sopenharmony_ci // https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.from_raw_parts 4133d722a9Sopenharmony_ci // https://github.com/rust-lang/rust/issues/81513 4233d722a9Sopenharmony_ci let ptr = ptr::slice_from_raw_parts_mut(ptr.as_ptr().cast(), len); 4333d722a9Sopenharmony_ci unsafe { mem::transmute::<NonNull<[()]>, RustSlice>(NonNull::new_unchecked(ptr)) } 4433d722a9Sopenharmony_ci } 4533d722a9Sopenharmony_ci 4633d722a9Sopenharmony_ci pub(crate) fn as_non_null_ptr<T>(&self) -> NonNull<T> { 4733d722a9Sopenharmony_ci let rust_slice = RustSlice { repr: self.repr }; 4833d722a9Sopenharmony_ci let repr = unsafe { mem::transmute::<RustSlice, NonNull<[()]>>(rust_slice) }; 4933d722a9Sopenharmony_ci repr.cast() 5033d722a9Sopenharmony_ci } 5133d722a9Sopenharmony_ci 5233d722a9Sopenharmony_ci pub(crate) fn len(&self) -> usize { 5333d722a9Sopenharmony_ci let rust_slice = RustSlice { repr: self.repr }; 5433d722a9Sopenharmony_ci let repr = unsafe { mem::transmute::<RustSlice, NonNull<[()]>>(rust_slice) }; 5533d722a9Sopenharmony_ci // TODO: use repr.len() when stable. 5633d722a9Sopenharmony_ci // https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.len 5733d722a9Sopenharmony_ci // https://github.com/rust-lang/rust/issues/71146 5833d722a9Sopenharmony_ci unsafe { repr.as_ref() }.len() 5933d722a9Sopenharmony_ci } 6033d722a9Sopenharmony_ci} 6133d722a9Sopenharmony_ci 6233d722a9Sopenharmony_ciconst_assert_eq!(mem::size_of::<NonNull<[()]>>(), mem::size_of::<RustSlice>()); 6333d722a9Sopenharmony_ciconst_assert_eq!( 6433d722a9Sopenharmony_ci mem::align_of::<NonNull<[()]>>(), 6533d722a9Sopenharmony_ci mem::align_of::<RustSlice>(), 6633d722a9Sopenharmony_ci); 67