movable_ref/offset/
integers.rs1use super::delta::{Nullable, Offset};
2use crate::error::{IntegerOffsetError, IntegerOffsetErrorImpl};
3use crate::pointer::unreachable::{UncheckedOptionExt, OVERFLOW_SUB};
4
5macro_rules! impl_delta_zeroable {
6 ($($type:ty),* $(,)?) => {$(
7 unsafe impl Offset for $type {
8 type Error = IntegerOffsetError;
9
10 fn sub(a: *mut u8, b: *mut u8) -> Result<Self, Self::Error> {
11 let del = match isize::checked_sub(a as usize as _, b as usize as _) {
12 Some(del) => del,
13 None => return Err(IntegerOffsetError(IntegerOffsetErrorImpl::Sub(a as usize, b as usize)))
14 };
15
16 if std::mem::size_of::<Self>() < std::mem::size_of::<isize>() && (
17 (Self::MIN as isize) > del ||
18 (Self::MAX as isize) < del
19 )
20 {
21 Err(IntegerOffsetError(IntegerOffsetErrorImpl::Conversion(del)))
22 } else {
23 Ok(del as _)
24 }
25 }
26
27 unsafe fn sub_unchecked(a: *mut u8, b: *mut u8) -> Self {
28 isize::checked_sub(a as usize as _, b as usize as _).unchecked_unwrap(OVERFLOW_SUB) as _
29 }
30
31 unsafe fn add(self, a: *const u8) -> *mut u8 {
32 <*const u8>::offset(a, self as isize) as *mut u8
33 }
34 }
35
36 impl Nullable for $type {
37 const NULL: Self = 0;
38 }
39 )*};
40}
41
42impl_delta_zeroable! { i8, i16, i32, i64, i128, isize }