use super::*;
use std::ops::{Bound, Range, RangeBounds};
#[inline]
fn clip_range(r: impl RangeBounds<usize>, upper: usize) -> Range<usize> {
let start = match r.start_bound() {
Bound::Included(&s) => s,
Bound::Excluded(&s) => s + 1,
Bound::Unbounded => 0,
};
let end = match r.end_bound() {
Bound::Included(&e) => e + 1,
Bound::Excluded(&e) => e,
Bound::Unbounded => upper,
};
start..end
}
#[allow(private_bounds)]
#[allow(clippy::len_without_is_empty)]
pub unsafe trait Slicing<'s>: private::Sealed {
type Output: 's;
fn addr(&'s self) -> *mut u8;
fn len(&'s self) -> usize;
fn as_slice(&'s self) -> Self::Output {
unsafe { self.slice_unchecked(0, self.len()) }
}
fn slice(&'s self, offset: usize, len: usize) -> Option<Self::Output> {
if offset < self.len() && len <= self.len() - offset {
Some(unsafe { self.slice_unchecked(offset, len) })
} else {
None
}
}
fn slice_by_range(&'s self, range: impl RangeBounds<usize>) -> Option<Self::Output> {
let r = clip_range(range, self.len());
self.slice(r.start, r.len())
}
fn slice_by_ptr(&'s self, pointer: *mut u8, len: usize) -> Option<Self::Output> {
if pointer >= self.addr() {
self.slice((pointer as usize) - (self.addr() as usize), len)
} else {
None
}
}
unsafe fn slice_unchecked(&'s self, offset: usize, len: usize) -> Self::Output;
unsafe fn slice_by_range_unchecked(&'s self, range: impl RangeBounds<usize>) -> Self::Output {
let r = clip_range(range, self.len());
self.slice_unchecked(r.start, r.len())
}
unsafe fn slice_by_ptr_unchecked(&'s self, pointer: *mut u8, len: usize) -> Self::Output {
self.slice_unchecked((pointer as usize) - (self.addr() as usize), len)
}
}
mod private {
pub trait Sealed {}
}
impl private::Sealed for Mr {}
impl private::Sealed for MrSlice<'_> {}
impl private::Sealed for MrRemote {}
impl private::Sealed for crate::wrap::RegisteredMem {}