use crate::{
def::{NSTDAny, NSTDAnyConst, NSTDBool},
pointer::NSTDPointer,
range::NSTDURange,
};
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct NSTDSlice {
pub size: usize,
pub ptr: NSTDPointer,
}
impl NSTDSlice {
#[inline]
pub fn byte_count(&self) -> usize {
self.size * self.ptr.size
}
#[inline]
pub unsafe fn end_unchecked(&self) -> *mut u8 {
self.ptr.raw.add(self.byte_count()).cast()
}
}
impl NSTDSlice {
#[inline]
pub unsafe fn as_byte_slice(&self) -> &[u8] {
core::slice::from_raw_parts(self.ptr.raw.cast(), self.byte_count())
}
#[inline]
pub unsafe fn as_byte_slice_mut(&mut self) -> &mut [u8] {
core::slice::from_raw_parts_mut(self.ptr.raw.cast(), self.byte_count())
}
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_new(
size: usize,
element_size: usize,
data: NSTDAny,
) -> NSTDSlice {
NSTDSlice {
size,
ptr: crate::pointer::nstd_core_pointer_new(data, element_size),
}
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_get(slice: &NSTDSlice, pos: usize) -> NSTDAny {
match slice.size > pos {
true => slice.ptr.raw.add(pos * slice.ptr.size),
false => core::ptr::null_mut(),
}
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_first(slice: &NSTDSlice) -> NSTDAny {
match slice.size > 0 {
true => slice.ptr.raw,
false => core::ptr::null_mut(),
}
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_last(slice: &NSTDSlice) -> NSTDAny {
match slice.size > 0 {
true => slice.end_unchecked().sub(slice.ptr.size).cast(),
false => core::ptr::null_mut(),
}
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_compare(s1: &NSTDSlice, s2: &NSTDSlice) -> NSTDBool {
if s1.size == s2.size {
return NSTDBool::from(s1.as_byte_slice() == s2.as_byte_slice());
}
NSTDBool::NSTD_BOOL_FALSE
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_contains(
slice: &NSTDSlice,
element: NSTDAnyConst,
) -> NSTDBool {
let mut ptr = slice.ptr.raw as *const u8;
let element = core::slice::from_raw_parts(element.cast(), slice.ptr.size);
for _ in 0..slice.size {
let data = core::slice::from_raw_parts(ptr, slice.ptr.size);
if data == element {
return NSTDBool::NSTD_BOOL_TRUE;
}
ptr = ptr.add(slice.ptr.size);
}
NSTDBool::NSTD_BOOL_FALSE
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_count(slice: &NSTDSlice, element: NSTDAnyConst) -> usize {
let mut ptr = slice.ptr.raw as *const u8;
let element = core::slice::from_raw_parts(element.cast(), slice.ptr.size);
let mut count = 0;
for _ in 0..slice.size {
let data = core::slice::from_raw_parts(ptr, slice.ptr.size);
if data == element {
count += 1;
}
ptr = ptr.add(slice.ptr.size);
}
count
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_find_first(
slice: &NSTDSlice,
element: NSTDAnyConst,
) -> usize {
let mut ptr = slice.ptr.raw as *const u8;
let element = core::slice::from_raw_parts(element.cast(), slice.ptr.size);
for i in 0..slice.size {
let data = core::slice::from_raw_parts(ptr, slice.ptr.size);
if data == element {
return i;
}
ptr = ptr.add(slice.ptr.size);
}
usize::MAX
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_find_last(
slice: &NSTDSlice,
element: NSTDAnyConst,
) -> usize {
let mut ptr = slice.end_unchecked().sub(slice.ptr.size);
let element = core::slice::from_raw_parts(element.cast(), slice.ptr.size);
for i in (0..slice.size).rev() {
let data = core::slice::from_raw_parts(ptr, slice.ptr.size);
if data == element {
return i;
}
ptr = ptr.sub(slice.ptr.size);
}
usize::MAX
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_starts_with(
slice: &NSTDSlice,
pattern: &NSTDSlice,
) -> NSTDBool {
let slice = slice.as_byte_slice();
let pattern = pattern.as_byte_slice();
NSTDBool::from(slice.starts_with(pattern))
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_ends_with(
slice: &NSTDSlice,
pattern: &NSTDSlice,
) -> NSTDBool {
let slice = slice.as_byte_slice();
let pattern = pattern.as_byte_slice();
NSTDBool::from(slice.ends_with(pattern))
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_fill(slice: &mut NSTDSlice, element: NSTDAnyConst) {
nstd_core_slice_fill_range(
slice,
element,
&NSTDURange {
start: 0,
end: slice.size,
},
);
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_fill_range(
slice: &mut NSTDSlice,
element: NSTDAnyConst,
range: &NSTDURange,
) {
let element = core::slice::from_raw_parts(element as *const u8, slice.ptr.size);
let start = range.start * slice.ptr.size;
let mut ptr = slice.ptr.raw.add(start).cast();
for _ in range.start..range.end {
let data = core::slice::from_raw_parts_mut(ptr, slice.ptr.size);
data.copy_from_slice(element);
ptr = ptr.add(slice.ptr.size);
}
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_swap(slice: &mut NSTDSlice, i: usize, j: usize) {
let i = slice.ptr.raw.add(slice.ptr.size * i);
let j = slice.ptr.raw.add(slice.ptr.size * j);
let slicei = core::slice::from_raw_parts_mut(i, slice.ptr.size);
let slicej = core::slice::from_raw_parts_mut(j, slice.ptr.size);
slicei.swap_with_slice(slicej);
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_reverse(slice: &mut NSTDSlice) {
let mut ptr = slice.ptr.raw as *mut u8;
let mut data = slice.as_byte_slice_mut();
data.reverse();
for _ in 0..slice.size {
data = core::slice::from_raw_parts_mut(ptr, slice.ptr.size);
data.reverse();
ptr = ptr.add(slice.ptr.size);
}
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_shift_right(slice: &mut NSTDSlice, x: usize) {
let rot = x % slice.size * slice.ptr.size;
slice.as_byte_slice_mut().rotate_right(rot);
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_shift_left(slice: &mut NSTDSlice, x: usize) {
let rot = x % slice.size * slice.ptr.size;
slice.as_byte_slice_mut().rotate_left(rot);
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_copy_from_slice(s1: &mut NSTDSlice, s2: &NSTDSlice) {
let bc1 = s1.byte_count();
let bc2 = s2.byte_count();
if bc1 == bc2 {
let s1 = s1.as_byte_slice_mut();
let s2 = s2.as_byte_slice();
s1.copy_from_slice(s2);
}
}
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_swap_with_slice(s1: &mut NSTDSlice, s2: &mut NSTDSlice) {
let bc1 = s1.byte_count();
let bc2 = s2.byte_count();
if bc1 == bc2 {
let s1 = s1.as_byte_slice_mut();
let s2 = s2.as_byte_slice_mut();
s1.swap_with_slice(s2);
}
}
#[inline]
#[cfg_attr(feature = "clib", no_mangle)]
pub unsafe extern "C" fn nstd_core_slice_move(s1: &mut NSTDSlice, s2: &mut NSTDSlice) {
const BYTE_SIZE: usize = core::mem::size_of::<u8>();
nstd_core_slice_copy_from_slice(s1, s2);
let mut s2 = nstd_core_slice_new(s2.byte_count(), BYTE_SIZE, s2.ptr.raw);
nstd_core_slice_fill(&mut s2, (&0u8 as *const u8) as NSTDAny);
}