cxx/
rust_slice.rs
1#![allow(missing_docs)]
2
3use core::mem::{self, MaybeUninit};
4use core::ptr::{self, NonNull};
5use core::slice;
6
7#[repr(C)]
9pub struct RustSlice {
10 repr: [MaybeUninit<usize>; mem::size_of::<NonNull<[()]>>() / mem::size_of::<usize>()],
11}
12
13impl RustSlice {
14 pub fn from_ref<T>(slice: &[T]) -> Self {
15 let ptr = NonNull::from(slice).cast::<T>();
16 let len = slice.len();
17 Self::from_raw_parts(ptr, len)
18 }
19
20 pub fn from_mut<T>(slice: &mut [T]) -> Self {
21 let ptr = NonNull::from(&mut *slice).cast::<T>();
22 let len = slice.len();
23 Self::from_raw_parts(ptr, len)
24 }
25
26 pub unsafe fn as_slice<'a, T>(self) -> &'a [T] {
27 let ptr = self.as_non_null_ptr().as_ptr();
28 let len = self.len();
29 unsafe { slice::from_raw_parts(ptr, len) }
30 }
31
32 pub unsafe fn as_mut_slice<'a, T>(self) -> &'a mut [T] {
33 let ptr = self.as_non_null_ptr().as_ptr();
34 let len = self.len();
35 unsafe { slice::from_raw_parts_mut(ptr, len) }
36 }
37
38 pub(crate) fn from_raw_parts<T>(ptr: NonNull<T>, len: usize) -> Self {
39 let ptr = ptr::slice_from_raw_parts_mut(ptr.as_ptr().cast(), len);
43 unsafe { mem::transmute::<NonNull<[()]>, RustSlice>(NonNull::new_unchecked(ptr)) }
44 }
45
46 pub(crate) fn as_non_null_ptr<T>(&self) -> NonNull<T> {
47 let rust_slice = RustSlice { repr: self.repr };
48 let repr = unsafe { mem::transmute::<RustSlice, NonNull<[()]>>(rust_slice) };
49 repr.cast()
50 }
51
52 pub(crate) fn len(&self) -> usize {
53 let rust_slice = RustSlice { repr: self.repr };
54 let repr = unsafe { mem::transmute::<RustSlice, NonNull<[()]>>(rust_slice) };
55 unsafe { repr.as_ref() }.len()
59 }
60}
61
62const_assert_eq!(mem::size_of::<NonNull<[()]>>(), mem::size_of::<RustSlice>());
63const_assert_eq!(
64 mem::align_of::<NonNull<[()]>>(),
65 mem::align_of::<RustSlice>(),
66);