use crate::{simd, ValidLayout};
use crate::mask::{Mask, MaskLayout};
use crate::num::{SimdInt, SimdUint};
use crate::ptr::SimdConstPtr;
use crate::simd::{Simd, SimdLayout, SimdScalar};
use core::ptr;
impl<T, const N: usize> crate::ptr::seal::SimdConstPtr for Simd<*const T, N>
where
T: Sized,
SimdLayout<*const T, N>: ValidLayout,
SimdLayout<usize, N>: ValidLayout,
{}
impl<T, const N: usize> SimdConstPtr<T, N> for Simd<*const T, N>
where
T: Sized,
SimdLayout<*const T, N>: ValidLayout,
SimdLayout<usize, N>: ValidLayout,
{
#[inline(always)]
fn null() -> Self {
simd![ptr::null(); N]
}
#[inline]
fn dangling() -> Self {
simd![ptr::dangling(); N]
}
#[inline]
fn with_exposed_provenance(addr: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
addr.map(ptr::with_exposed_provenance)
}
#[inline(always)]
fn without_provenance(addr: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
unsafe { addr.transmute() }
}
#[inline]
#[track_caller]
unsafe fn offset(self, count: Simd<isize, N>) -> Self
where
SimdLayout<isize, N>: ValidLayout,
{
self.wrapping_offset(count)
}
#[inline]
#[track_caller]
unsafe fn byte_offset(self, count: Simd<isize, N>) -> Self
where
SimdLayout<isize, N>: ValidLayout,
{
self.wrapping_byte_offset(count)
}
#[inline]
#[track_caller]
unsafe fn add(self, count: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
self.wrapping_add(count)
}
#[inline]
#[track_caller]
unsafe fn byte_add(self, count: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
self.wrapping_byte_add(count)
}
#[inline]
#[track_caller]
unsafe fn sub(self, count: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
self.wrapping_sub(count)
}
#[inline]
#[track_caller]
unsafe fn byte_sub(self, count: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
self.wrapping_byte_sub(count)
}
#[inline]
#[track_caller]
fn wrapping_offset(self, mut count: Simd<isize, N>) -> Self
where
SimdLayout<isize, N>: ValidLayout,
{
count = unsafe { count.unchecked_mul(simd![size_of::<T>().cast_signed(); N]) };
let addr = self.expose_provenance().wrapping_add_signed(count);
Self::with_exposed_provenance(addr)
}
#[inline]
#[track_caller]
fn wrapping_byte_offset(self, count: Simd<isize, N>) -> Self
where
SimdLayout<isize, N>: ValidLayout,
{
let addr = self.expose_provenance().wrapping_add_signed(count);
Self::with_exposed_provenance(addr)
}
#[inline]
#[track_caller]
fn wrapping_add(self, mut count: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
count = unsafe { count.unchecked_mul(simd![size_of::<T>(); N]) };
let addr = self.expose_provenance().wrapping_add(count);
Self::with_exposed_provenance(addr)
}
#[inline]
#[track_caller]
fn wrapping_byte_add(self, count: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
let addr = self.expose_provenance().wrapping_add(count);
Self::with_exposed_provenance(addr)
}
#[inline]
#[track_caller]
fn wrapping_sub(self, mut count: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
count = unsafe { count.unchecked_mul(simd![size_of::<T>(); N]) };
let addr = self.expose_provenance().wrapping_sub(count);
Self::with_exposed_provenance(addr)
}
#[inline]
#[track_caller]
fn wrapping_byte_sub(self, count: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
let addr = self.expose_provenance().wrapping_sub(count);
Self::with_exposed_provenance(addr)
}
#[inline]
#[track_caller]
fn map_addr<F>(self, op: F) -> Self
where
F: FnMut(usize) -> usize,
SimdLayout<usize, N>: ValidLayout,
{
let addr = self.expose_provenance().map(op);
Self::with_exposed_provenance(addr)
}
#[inline]
#[track_caller]
unsafe fn read(self) -> Simd<T, N>
where
T: SimdScalar,
SimdLayout<T, N>: ValidLayout,
{
self.map(|p| unsafe { p.read() })
}
#[inline]
#[track_caller]
unsafe fn read_volatile(self) -> Simd<T, N>
where
T: SimdScalar,
SimdLayout<T, N>: ValidLayout,
{
self.map(|p| unsafe { p.read_volatile() })
}
#[inline]
#[track_caller]
unsafe fn read_unaligned(self) -> Simd<T, N>
where
T: SimdScalar,
SimdLayout<T, N>: ValidLayout,
{
self.map(|p| unsafe { p.read_unaligned() })
}
#[inline]
#[track_caller]
fn addr(self) -> Simd<usize, N>
where
SimdLayout<usize, N>: ValidLayout,
{
unsafe { self.transmute() }
}
#[inline]
#[track_caller]
fn align_offset(self, align: Simd<usize, N>) -> Simd<usize, N>
where
SimdLayout<usize, N>: ValidLayout,
{
self.zip_with(align, <*const T>::align_offset)
}
#[inline]
#[track_caller]
fn is_null(self) -> Mask<N>
where
MaskLayout<N>: ValidLayout,
{
self.to_array().map(<*const T>::is_null).into()
}
#[inline]
#[track_caller]
fn is_aligned(self) -> Mask<N>
where
MaskLayout<N>: ValidLayout,
{
self.to_array().map(<*const T>::is_aligned).into()
}
#[inline]
#[track_caller]
fn with_addr(self, addr: Simd<usize, N>) -> Self
where
SimdLayout<usize, N>: ValidLayout,
{
let offset = addr.wrapping_sub(self.addr());
self.wrapping_byte_add(offset)
}
#[inline]
#[track_caller]
fn cast<U>(self) -> Simd<*const U, N>
where
U: Sized,
SimdLayout<*const U, N>: ValidLayout,
{
self.map(<*const T>::cast)
}
#[inline]
#[track_caller]
fn cast_mut(self) -> Simd<*mut T, N>
where
SimdLayout<*mut T, N>: ValidLayout,
{
self.map(<*const T>::cast_mut)
}
#[inline]
#[track_caller]
fn expose_provenance(self) -> Simd<usize, N>
where
SimdLayout<usize, N>: ValidLayout,
{
self.map(<*const T>::expose_provenance)
}
}