use core::{
alloc::{Layout, LayoutError},
marker::PhantomData,
ptr::{NonNull, drop_in_place},
};
use private::Sealed;
pub unsafe trait SoAble: Sized {
type TupleRepr: SoATuple;
const MUST_DROP_AS_SELF: bool = false;
type Ref<'a>: Copy
where
Self: 'a;
type Mut<'a>
where
Self: 'a;
type Slice<'a>: Copy
where
Self: 'a;
type SliceMut<'a>
where
Self: 'a;
fn into_tuple(value: Self) -> Self::TupleRepr;
fn from_tuple(value: Self::TupleRepr) -> Self;
fn as_ref<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Ref<'a>;
fn as_mut<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Mut<'a>;
fn as_slice<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::Slice<'a>;
fn as_mut_slice<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::SliceMut<'a>;
}
mod private {
pub trait Sealed {}
impl<T, U> Sealed for (T, U) {}
impl<T, U, V> Sealed for (T, U, V) {}
impl<T, U, V, W> Sealed for (T, U, V, W) {}
impl<T, U, V, W, X> Sealed for (T, U, V, W, X) {}
}
pub trait SoATuple: Sealed {
type Offsets: Copy;
type Pointers: Copy;
fn layout(capacity: u32) -> Result<Layout, LayoutError>;
fn get_offsets(capacity: u32) -> Self::Offsets;
unsafe fn grow(base: NonNull<u8>, new_capacity: u32, old_capacity: u32, len: u32);
#[must_use]
unsafe fn read(base: NonNull<u8>, index: u32, capacity: u32) -> Self;
unsafe fn write(base: NonNull<u8>, src: Self, index: u32, capacity: u32);
unsafe fn copy(src: Self::Pointers, dst: Self::Pointers, count: u32);
unsafe fn drop_in_place(ptrs: Self::Pointers, len: u32);
unsafe fn get_pointers(base: NonNull<u8>, index: u32, capacity: u32) -> Self::Pointers;
}
impl<T, U> SoATuple for (T, U) {
type Offsets = (usize,);
type Pointers = (NonNull<T>, NonNull<U>);
fn layout(capacity: u32) -> Result<Layout, LayoutError> {
Ok(layout_array::<T>(capacity)?
.extend(layout_array::<U>(capacity)?)?
.0
.pad_to_align())
}
fn get_offsets(capacity: u32) -> (usize,) {
unsafe {
let layout = layout_array::<T>(capacity).unwrap_unchecked();
let (_, u_offset) = extend_layout_array::<U>(layout, capacity).unwrap_unchecked();
(u_offset,)
}
}
unsafe fn grow(base: NonNull<u8>, new_capacity: u32, old_capacity: u32, len: u32) {
if size_of::<Self>() == 0 || len == 0 {
return;
}
debug_assert!(base.cast::<Self>().is_aligned());
debug_assert!(old_capacity < new_capacity);
unsafe {
let (_, old_u_ptr) = Self::get_pointers(base, 0, old_capacity);
let (_, new_u_ptr) = Self::get_pointers(base, 0, new_capacity);
core::ptr::copy(old_u_ptr.as_ptr(), new_u_ptr.as_ptr(), len as usize);
};
}
unsafe fn read(ptr: NonNull<u8>, index: u32, capacity: u32) -> Self {
unsafe {
let ptr = Self::get_pointers(ptr, index, capacity);
(ptr.0.read(), ptr.1.read())
}
}
unsafe fn write(base: NonNull<u8>, data: Self, index: u32, capacity: u32) {
debug_assert!(base.cast::<Self>().is_aligned());
unsafe {
let (t_ptr, u_ptr) = Self::get_pointers(base, index, capacity);
t_ptr.write(data.0);
u_ptr.write(data.1);
}
}
unsafe fn copy(src: Self::Pointers, dst: Self::Pointers, len: u32) {
if size_of::<Self>() == 0 || len == 0 {
return;
}
let (src_t_ptr, src_u_ptr) = src;
let (dst_t_ptr, dst_u_ptr) = dst;
unsafe {
core::ptr::copy(src_u_ptr.as_ptr(), dst_u_ptr.as_ptr(), len as usize);
core::ptr::copy(src_t_ptr.as_ptr(), dst_t_ptr.as_ptr(), len as usize);
};
}
unsafe fn drop_in_place(ptrs: Self::Pointers, len: u32) {
assert!(core::mem::needs_drop::<Self>());
let (t_ptr, u_ptr) = ptrs;
if core::mem::needs_drop::<T>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
t_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<U>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
u_ptr.as_ptr(),
len as usize,
));
}
}
}
unsafe fn get_pointers(ptr: NonNull<u8>, index: u32, capacity: u32) -> Self::Pointers {
debug_assert!(ptr.cast::<Self>().is_aligned());
let (u_offset,) = Self::get_offsets(capacity);
unsafe {
let t_ptr = ptr.cast::<T>().add(index as usize);
debug_assert!(t_ptr.is_aligned());
let u_ptr = ptr.byte_add(u_offset).cast::<U>().add(index as usize);
debug_assert!(u_ptr.is_aligned());
(t_ptr, u_ptr)
}
}
}
impl<T, U, V> SoATuple for (T, U, V) {
type Offsets = (usize, usize);
type Pointers = (NonNull<T>, NonNull<U>, NonNull<V>);
fn layout(capacity: u32) -> Result<Layout, LayoutError> {
Ok(layout_array::<T>(capacity)?
.extend(layout_array::<U>(capacity)?)?
.0
.extend(layout_array::<V>(capacity)?)?
.0
.pad_to_align())
}
fn get_offsets(capacity: u32) -> Self::Offsets {
unsafe {
let layout = layout_array::<T>(capacity).unwrap_unchecked();
let (layout, u_offset) = extend_layout_array::<U>(layout, capacity).unwrap_unchecked();
let (_, v_offset) = extend_layout_array::<V>(layout, capacity).unwrap_unchecked();
(u_offset, v_offset)
}
}
unsafe fn read(ptr: NonNull<u8>, index: u32, capacity: u32) -> Self {
unsafe {
let ptr = Self::get_pointers(ptr, index, capacity);
(ptr.0.read(), ptr.1.read(), ptr.2.read())
}
}
unsafe fn grow(base: NonNull<u8>, new_capacity: u32, old_capacity: u32, len: u32) {
if size_of::<Self>() == 0 || len == 0 {
return;
}
debug_assert!(base.cast::<Self>().is_aligned());
debug_assert!(old_capacity < new_capacity);
unsafe {
let (_, old_u_ptr, old_v_ptr) = Self::get_pointers(base, 0, old_capacity);
let (_, new_u_ptr, new_v_ptr) = Self::get_pointers(base, 0, new_capacity);
core::ptr::copy(old_v_ptr.as_ptr(), new_v_ptr.as_ptr(), len as usize);
core::ptr::copy(old_u_ptr.as_ptr(), new_u_ptr.as_ptr(), len as usize);
};
}
unsafe fn write(base: NonNull<u8>, data: Self, index: u32, capacity: u32) {
debug_assert!(base.cast::<Self>().is_aligned());
unsafe {
let (t_ptr, u_ptr, v_ptr) = Self::get_pointers(base, index, capacity);
t_ptr.write(data.0);
u_ptr.write(data.1);
v_ptr.write(data.2);
}
}
unsafe fn copy(src: Self::Pointers, dst: Self::Pointers, len: u32) {
if size_of::<Self>() == 0 || len == 0 {
return;
}
let (src_t_ptr, src_u_ptr, src_v_ptr) = src;
let (dst_t_ptr, dst_u_ptr, dst_v_ptr) = dst;
unsafe {
core::ptr::copy(src_v_ptr.as_ptr(), dst_v_ptr.as_ptr(), len as usize);
core::ptr::copy(src_u_ptr.as_ptr(), dst_u_ptr.as_ptr(), len as usize);
core::ptr::copy(src_t_ptr.as_ptr(), dst_t_ptr.as_ptr(), len as usize);
};
}
unsafe fn drop_in_place(ptrs: Self::Pointers, len: u32) {
assert!(core::mem::needs_drop::<Self>());
let (t_ptr, u_ptr, v_ptr) = ptrs;
if core::mem::needs_drop::<T>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
t_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<U>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
u_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<V>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
v_ptr.as_ptr(),
len as usize,
));
}
}
}
unsafe fn get_pointers(ptr: NonNull<u8>, index: u32, capacity: u32) -> Self::Pointers {
debug_assert!(ptr.cast::<Self>().is_aligned());
let (u_offset, v_offset) = Self::get_offsets(capacity);
unsafe {
let t_ptr = ptr.cast::<T>().add(index as usize);
debug_assert!(t_ptr.is_aligned());
let u_ptr = ptr.byte_add(u_offset).cast::<U>().add(index as usize);
debug_assert!(u_ptr.is_aligned());
let v_ptr = ptr.byte_add(v_offset).cast::<V>().add(index as usize);
debug_assert!(v_ptr.is_aligned());
(t_ptr, u_ptr, v_ptr)
}
}
}
impl<T, U, V, W> SoATuple for (T, U, V, W) {
type Offsets = (usize, usize, usize);
type Pointers = (NonNull<T>, NonNull<U>, NonNull<V>, NonNull<W>);
fn layout(capacity: u32) -> Result<Layout, LayoutError> {
Ok(layout_array::<T>(capacity)?
.extend(layout_array::<U>(capacity)?)?
.0
.extend(layout_array::<V>(capacity)?)?
.0
.extend(layout_array::<W>(capacity)?)?
.0
.pad_to_align())
}
fn get_offsets(capacity: u32) -> Self::Offsets {
unsafe {
let layout = layout_array::<T>(capacity).unwrap_unchecked();
let (layout, u_offset) = extend_layout_array::<U>(layout, capacity).unwrap_unchecked();
let (layout, v_offset) = extend_layout_array::<V>(layout, capacity).unwrap_unchecked();
let (_, w_offset) = extend_layout_array::<W>(layout, capacity).unwrap_unchecked();
(u_offset, v_offset, w_offset)
}
}
unsafe fn read(ptr: NonNull<u8>, index: u32, capacity: u32) -> Self {
unsafe {
let ptr = Self::get_pointers(ptr, index, capacity);
(ptr.0.read(), ptr.1.read(), ptr.2.read(), ptr.3.read())
}
}
unsafe fn grow(base: NonNull<u8>, new_capacity: u32, old_capacity: u32, len: u32) {
if size_of::<Self>() == 0 || len == 0 {
return;
}
debug_assert!(base.cast::<Self>().is_aligned());
debug_assert!(old_capacity < new_capacity);
unsafe {
let (_, old_u_ptr, old_v_ptr, old_w_ptr) = Self::get_pointers(base, 0, old_capacity);
let (_, new_u_ptr, new_v_ptr, new_w_ptr) = Self::get_pointers(base, 0, new_capacity);
core::ptr::copy(old_w_ptr.as_ptr(), new_w_ptr.as_ptr(), len as usize);
core::ptr::copy(old_v_ptr.as_ptr(), new_v_ptr.as_ptr(), len as usize);
core::ptr::copy(old_u_ptr.as_ptr(), new_u_ptr.as_ptr(), len as usize);
};
}
unsafe fn write(base: NonNull<u8>, data: Self, index: u32, capacity: u32) {
debug_assert!(base.cast::<Self>().is_aligned());
unsafe {
let (t_ptr, u_ptr, v_ptr, w_ptr) = Self::get_pointers(base, index, capacity);
t_ptr.write(data.0);
u_ptr.write(data.1);
v_ptr.write(data.2);
w_ptr.write(data.3);
}
}
unsafe fn drop_in_place(ptrs: Self::Pointers, len: u32) {
assert!(core::mem::needs_drop::<Self>());
let (t_ptr, u_ptr, v_ptr, w_ptr) = ptrs;
if core::mem::needs_drop::<T>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
t_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<U>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
u_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<V>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
v_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<W>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
w_ptr.as_ptr(),
len as usize,
));
}
}
}
unsafe fn copy(src: Self::Pointers, dst: Self::Pointers, len: u32) {
if size_of::<Self>() == 0 || len == 0 {
return;
}
let (src_t_ptr, src_u_ptr, src_v_ptr, src_w_ptr) = src;
let (dst_t_ptr, dst_u_ptr, dst_v_ptr, dst_w_ptr) = dst;
unsafe {
core::ptr::copy(src_w_ptr.as_ptr(), dst_w_ptr.as_ptr(), len as usize);
core::ptr::copy(src_v_ptr.as_ptr(), dst_v_ptr.as_ptr(), len as usize);
core::ptr::copy(src_u_ptr.as_ptr(), dst_u_ptr.as_ptr(), len as usize);
core::ptr::copy(src_t_ptr.as_ptr(), dst_t_ptr.as_ptr(), len as usize);
};
}
unsafe fn get_pointers(ptr: NonNull<u8>, index: u32, capacity: u32) -> Self::Pointers {
debug_assert!(ptr.cast::<Self>().is_aligned());
let (u_offset, v_offset, w_offset) = Self::get_offsets(capacity);
unsafe {
let t_ptr = ptr.cast::<T>().add(index as usize);
debug_assert!(t_ptr.is_aligned());
let u_ptr = ptr.byte_add(u_offset).cast::<U>().add(index as usize);
debug_assert!(u_ptr.is_aligned());
let v_ptr = ptr.byte_add(v_offset).cast::<V>().add(index as usize);
debug_assert!(v_ptr.is_aligned());
let w_ptr = ptr.byte_add(w_offset).cast::<W>().add(index as usize);
debug_assert!(w_ptr.is_aligned());
(t_ptr, u_ptr, v_ptr, w_ptr)
}
}
}
impl<T, U, V, W, X> SoATuple for (T, U, V, W, X) {
type Offsets = (usize, usize, usize, usize);
type Pointers = (NonNull<T>, NonNull<U>, NonNull<V>, NonNull<W>, NonNull<X>);
fn layout(capacity: u32) -> Result<Layout, LayoutError> {
Ok(layout_array::<T>(capacity)?
.extend(layout_array::<U>(capacity)?)?
.0
.extend(layout_array::<V>(capacity)?)?
.0
.extend(layout_array::<W>(capacity)?)?
.0
.extend(layout_array::<X>(capacity)?)?
.0
.pad_to_align())
}
fn get_offsets(capacity: u32) -> Self::Offsets {
unsafe {
let layout = layout_array::<T>(capacity).unwrap_unchecked();
let (layout, u_offset) = extend_layout_array::<U>(layout, capacity).unwrap_unchecked();
let (layout, v_offset) = extend_layout_array::<V>(layout, capacity).unwrap_unchecked();
let (layout, w_offset) = extend_layout_array::<W>(layout, capacity).unwrap_unchecked();
let (_, x_offset) = extend_layout_array::<X>(layout, capacity).unwrap_unchecked();
(u_offset, v_offset, w_offset, x_offset)
}
}
unsafe fn read(ptr: NonNull<u8>, index: u32, capacity: u32) -> Self {
unsafe {
let ptr = Self::get_pointers(ptr, index, capacity);
(
ptr.0.read(),
ptr.1.read(),
ptr.2.read(),
ptr.3.read(),
ptr.4.read(),
)
}
}
unsafe fn grow(base: NonNull<u8>, new_capacity: u32, old_capacity: u32, len: u32) {
if size_of::<Self>() == 0 || len == 0 {
return;
}
debug_assert!(base.cast::<Self>().is_aligned());
debug_assert!(old_capacity < new_capacity);
unsafe {
let (_, old_u_ptr, old_v_ptr, old_w_ptr, old_x_ptr) =
Self::get_pointers(base, 0, old_capacity);
let (_, new_u_ptr, new_v_ptr, new_w_ptr, new_x_ptr) =
Self::get_pointers(base, 0, new_capacity);
core::ptr::copy(old_x_ptr.as_ptr(), new_x_ptr.as_ptr(), len as usize);
core::ptr::copy(old_w_ptr.as_ptr(), new_w_ptr.as_ptr(), len as usize);
core::ptr::copy(old_v_ptr.as_ptr(), new_v_ptr.as_ptr(), len as usize);
core::ptr::copy(old_u_ptr.as_ptr(), new_u_ptr.as_ptr(), len as usize);
};
}
unsafe fn write(base: NonNull<u8>, data: Self, index: u32, capacity: u32) {
debug_assert!(base.cast::<Self>().is_aligned());
let (t_ptr, u_ptr, v_ptr, w_ptr, x_ptr) =
unsafe { Self::get_pointers(base, index, capacity) };
unsafe {
t_ptr.write(data.0);
u_ptr.write(data.1);
v_ptr.write(data.2);
w_ptr.write(data.3);
x_ptr.write(data.4);
}
}
unsafe fn copy(src: Self::Pointers, dst: Self::Pointers, len: u32) {
if size_of::<Self>() == 0 || len == 0 {
return;
}
let (src_t_ptr, src_u_ptr, src_v_ptr, src_w_ptr, src_x_ptr) = src;
let (dst_t_ptr, dst_u_ptr, dst_v_ptr, dst_w_ptr, dst_x_ptr) = dst;
unsafe {
core::ptr::copy(src_t_ptr.as_ptr(), dst_t_ptr.as_ptr(), len as usize);
core::ptr::copy(src_x_ptr.as_ptr(), dst_x_ptr.as_ptr(), len as usize);
core::ptr::copy(src_w_ptr.as_ptr(), dst_w_ptr.as_ptr(), len as usize);
core::ptr::copy(src_v_ptr.as_ptr(), dst_v_ptr.as_ptr(), len as usize);
core::ptr::copy(src_u_ptr.as_ptr(), dst_u_ptr.as_ptr(), len as usize);
};
}
unsafe fn drop_in_place(ptrs: Self::Pointers, len: u32) {
assert!(core::mem::needs_drop::<Self>());
let (t_ptr, u_ptr, v_ptr, w_ptr, x_ptr) = ptrs;
if core::mem::needs_drop::<T>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
t_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<U>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
u_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<V>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
v_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<W>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
w_ptr.as_ptr(),
len as usize,
));
}
}
if core::mem::needs_drop::<X>() {
unsafe {
drop_in_place(core::ptr::slice_from_raw_parts_mut(
x_ptr.as_ptr(),
len as usize,
));
}
}
}
unsafe fn get_pointers(base: NonNull<u8>, index: u32, capacity: u32) -> Self::Pointers {
debug_assert!(base.cast::<Self>().is_aligned());
let (u_offset, v_offset, w_offset, x_offset) = Self::get_offsets(capacity);
unsafe {
let t_ptr = base.cast::<T>().add(index as usize);
debug_assert!(t_ptr.is_aligned());
let u_ptr = base.byte_add(u_offset).cast::<U>().add(index as usize);
debug_assert!(u_ptr.is_aligned());
let v_ptr = base.byte_add(v_offset).cast::<V>().add(index as usize);
debug_assert!(v_ptr.is_aligned());
let w_ptr = base.byte_add(w_offset).cast::<W>().add(index as usize);
debug_assert!(w_ptr.is_aligned());
let x_ptr = base.byte_add(x_offset).cast::<X>().add(index as usize);
debug_assert!(x_ptr.is_aligned());
(t_ptr, u_ptr, v_ptr, w_ptr, x_ptr)
}
}
}
#[inline]
fn extend_layout_array<T>(layout: Layout, cap: u32) -> Result<(Layout, usize), LayoutError> {
layout.extend(layout_array::<T>(cap)?)
}
#[inline]
fn layout_array<T>(cap: u32) -> Result<Layout, LayoutError> {
let elem_layout = Layout::new::<T>();
Layout::from_size_align(elem_layout.size() * cap as usize, elem_layout.align())
}
unsafe impl<T, U> SoAble for (T, U) {
type TupleRepr = Self;
type Ref<'a>
= (&'a T, &'a U)
where
Self: 'a;
type Mut<'a>
= (&'a mut T, &'a mut U)
where
Self: 'a;
type Slice<'a>
= (&'a [T], &'a [U])
where
Self: 'a;
type SliceMut<'a>
= (&'a mut [T], &'a mut [U])
where
Self: 'a;
fn into_tuple(value: Self) -> Self::TupleRepr {
value
}
fn from_tuple(value: Self::TupleRepr) -> Self {
value
}
fn as_ref<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Ref<'a> {
let (a, b) = value;
unsafe { (a.as_ref(), b.as_ref()) }
}
fn as_mut<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Mut<'a> {
let (mut a, mut b) = value;
unsafe { (a.as_mut(), b.as_mut()) }
}
fn as_slice<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::Slice<'a> {
let len = len as usize;
let (a, b) = value;
unsafe {
(
core::slice::from_raw_parts(a.as_ptr(), len),
core::slice::from_raw_parts(b.as_ptr(), len),
)
}
}
fn as_mut_slice<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::SliceMut<'a> {
let len = len as usize;
let (a, b) = value;
unsafe {
(
core::slice::from_raw_parts_mut(a.as_ptr(), len),
core::slice::from_raw_parts_mut(b.as_ptr(), len),
)
}
}
}
unsafe impl<T, U, V> SoAble for (T, U, V) {
type TupleRepr = Self;
type Ref<'a>
= (&'a T, &'a U, &'a V)
where
Self: 'a;
type Mut<'a>
= (&'a mut T, &'a mut U, &'a mut V)
where
Self: 'a;
type Slice<'a>
= (&'a [T], &'a [U], &'a [V])
where
Self: 'a;
type SliceMut<'a>
= (&'a mut [T], &'a mut [U], &'a mut [V])
where
Self: 'a;
fn into_tuple(value: Self) -> Self::TupleRepr {
value
}
fn from_tuple(value: Self::TupleRepr) -> Self {
value
}
fn as_ref<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Ref<'a> {
let (a, b, c) = value;
unsafe { (a.as_ref(), b.as_ref(), c.as_ref()) }
}
fn as_mut<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Mut<'a> {
let (mut a, mut b, mut c) = value;
unsafe { (a.as_mut(), b.as_mut(), c.as_mut()) }
}
fn as_slice<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::Slice<'a> {
let len = len as usize;
let (a, b, c) = value;
unsafe {
(
core::slice::from_raw_parts(a.as_ptr(), len),
core::slice::from_raw_parts(b.as_ptr(), len),
core::slice::from_raw_parts(c.as_ptr(), len),
)
}
}
fn as_mut_slice<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::SliceMut<'a> {
let len = len as usize;
let (a, b, c) = value;
unsafe {
(
core::slice::from_raw_parts_mut(a.as_ptr(), len),
core::slice::from_raw_parts_mut(b.as_ptr(), len),
core::slice::from_raw_parts_mut(c.as_ptr(), len),
)
}
}
}
unsafe impl<T, U, V, W> SoAble for (T, U, V, W) {
type TupleRepr = Self;
type Ref<'a>
= (&'a T, &'a U, &'a V, &'a W)
where
Self: 'a;
type Mut<'a>
= (&'a mut T, &'a mut U, &'a mut V, &'a mut W)
where
Self: 'a;
type Slice<'a>
= (&'a [T], &'a [U], &'a [V], &'a [W])
where
Self: 'a;
type SliceMut<'a>
= (&'a mut [T], &'a mut [U], &'a mut [V], &'a mut [W])
where
Self: 'a;
fn into_tuple(value: Self) -> Self::TupleRepr {
value
}
fn from_tuple(value: Self::TupleRepr) -> Self {
value
}
fn as_ref<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Ref<'a> {
let (a, b, c, d) = value;
unsafe { (a.as_ref(), b.as_ref(), c.as_ref(), d.as_ref()) }
}
fn as_mut<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Mut<'a> {
let (mut a, mut b, mut c, mut d) = value;
unsafe { (a.as_mut(), b.as_mut(), c.as_mut(), d.as_mut()) }
}
fn as_slice<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::Slice<'a> {
let len = len as usize;
let (a, b, c, d) = value;
unsafe {
(
core::slice::from_raw_parts(a.as_ptr(), len),
core::slice::from_raw_parts(b.as_ptr(), len),
core::slice::from_raw_parts(c.as_ptr(), len),
core::slice::from_raw_parts(d.as_ptr(), len),
)
}
}
fn as_mut_slice<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::SliceMut<'a> {
let len = len as usize;
let (a, b, c, d) = value;
unsafe {
(
core::slice::from_raw_parts_mut(a.as_ptr(), len),
core::slice::from_raw_parts_mut(b.as_ptr(), len),
core::slice::from_raw_parts_mut(c.as_ptr(), len),
core::slice::from_raw_parts_mut(d.as_ptr(), len),
)
}
}
}
unsafe impl<T, U, V, W, X> SoAble for (T, U, V, W, X) {
type TupleRepr = Self;
type Ref<'a>
= (&'a T, &'a U, &'a V, &'a W, &'a X)
where
Self: 'a;
type Mut<'a>
= (&'a mut T, &'a mut U, &'a mut V, &'a mut W, &'a mut X)
where
Self: 'a;
type Slice<'a>
= (&'a [T], &'a [U], &'a [V], &'a [W], &'a [X])
where
Self: 'a;
type SliceMut<'a>
= (
&'a mut [T],
&'a mut [U],
&'a mut [V],
&'a mut [W],
&'a mut [X],
)
where
Self: 'a;
fn into_tuple(value: Self) -> Self::TupleRepr {
value
}
fn from_tuple(value: Self::TupleRepr) -> Self {
value
}
fn as_ref<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Ref<'a> {
let (a, b, c, d, e) = value;
unsafe { (a.as_ref(), b.as_ref(), c.as_ref(), d.as_ref(), e.as_ref()) }
}
fn as_mut<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
) -> Self::Mut<'a> {
let (mut a, mut b, mut c, mut d, mut e) = value;
unsafe { (a.as_mut(), b.as_mut(), c.as_mut(), d.as_mut(), e.as_mut()) }
}
fn as_slice<'a>(
_: PhantomData<&'a Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::Slice<'a> {
let len = len as usize;
let (a, b, c, d, e) = value;
unsafe {
(
core::slice::from_raw_parts(a.as_ptr(), len),
core::slice::from_raw_parts(b.as_ptr(), len),
core::slice::from_raw_parts(c.as_ptr(), len),
core::slice::from_raw_parts(d.as_ptr(), len),
core::slice::from_raw_parts(e.as_ptr(), len),
)
}
}
fn as_mut_slice<'a>(
_: PhantomData<&'a mut Self>,
value: <Self::TupleRepr as SoATuple>::Pointers,
len: u32,
) -> Self::SliceMut<'a> {
let len = len as usize;
let (a, b, c, d, e) = value;
unsafe {
(
core::slice::from_raw_parts_mut(a.as_ptr(), len),
core::slice::from_raw_parts_mut(b.as_ptr(), len),
core::slice::from_raw_parts_mut(c.as_ptr(), len),
core::slice::from_raw_parts_mut(d.as_ptr(), len),
core::slice::from_raw_parts_mut(e.as_ptr(), len),
)
}
}
}