bump_scope/polyfill/
non_null.rs1use core::{
2 num::NonZeroUsize,
3 ops::Range,
4 ptr::{self, NonNull},
5};
6
7use crate::polyfill::pointer;
8
9#[must_use]
11#[inline(always)]
12pub(crate) unsafe fn offset_from_unsigned<T>(this: NonNull<T>, origin: NonNull<T>) -> usize {
13 unsafe { pointer::offset_from_unsigned(this.as_ptr(), origin.as_ptr()) }
14}
15
16#[must_use]
18#[inline(always)]
19pub(crate) unsafe fn byte_offset_from_unsigned<T>(this: NonNull<T>, origin: NonNull<T>) -> usize {
20 unsafe { offset_from_unsigned::<u8>(this.cast(), origin.cast()) }
21}
22
23#[inline(always)]
25pub(crate) fn is_aligned_to(ptr: NonNull<u8>, align: usize) -> bool {
26 debug_assert!(align.is_power_of_two());
27 ptr.addr().get() & (align - 1) == 0
28}
29
30#[inline(always)]
32pub(crate) const fn as_non_null_ptr<T>(ptr: NonNull<[T]>) -> NonNull<T> {
33 ptr.cast()
34}
35
36pub(crate) const fn from_ref<T>(r: &T) -> NonNull<T> {
38 unsafe { NonNull::new_unchecked(r as *const T as *mut T) }
39}
40
41#[must_use]
43#[inline]
44pub(crate) const fn without_provenance<T>(addr: NonZeroUsize) -> NonNull<T> {
45 let pointer = ptr::without_provenance_mut(addr.get());
46 unsafe { NonNull::new_unchecked(pointer) }
48}
49
50pub(crate) unsafe fn truncate<T>(slice: &mut NonNull<[T]>, len: usize) {
56 unsafe {
57 if len >= slice.len() {
69 return;
70 }
71
72 let remaining_len = slice.len() - len;
73
74 let to_drop_start = as_non_null_ptr(*slice).add(len);
75 let to_drop = NonNull::slice_from_raw_parts(to_drop_start, remaining_len);
76
77 set_len::<T>(slice, len);
78 to_drop.drop_in_place();
79 }
80}
81
82#[inline(always)]
84pub(crate) unsafe fn wrapping_byte_add<T>(ptr: NonNull<T>, count: usize) -> NonNull<T> {
85 unsafe { NonNull::new_unchecked(ptr.as_ptr().cast::<u8>().wrapping_add(count).cast()) }
86}
87
88#[inline(always)]
90pub(crate) unsafe fn wrapping_byte_sub<T>(ptr: NonNull<T>, count: usize) -> NonNull<T> {
91 unsafe { NonNull::new_unchecked(ptr.as_ptr().cast::<u8>().wrapping_sub(count).cast()) }
92}
93
94#[inline(always)]
96pub(crate) fn set_ptr<T>(ptr: &mut NonNull<[T]>, new_ptr: NonNull<T>) {
97 let len = ptr.len();
98 *ptr = NonNull::slice_from_raw_parts(new_ptr, len);
99}
100
101#[inline(always)]
103pub(crate) fn set_len<T>(ptr: &mut NonNull<[T]>, new_len: usize) {
104 let elem_ptr = as_non_null_ptr(*ptr);
105 *ptr = NonNull::slice_from_raw_parts(elem_ptr, new_len);
106}
107
108#[inline(always)]
110pub(crate) unsafe fn result<T, E>(mut ptr: NonNull<Result<T, E>>) -> Result<NonNull<T>, NonNull<E>> {
111 unsafe {
112 match ptr.as_mut() {
113 Ok(ok) => Ok(ok.into()),
114 Err(err) => Err(err.into()),
115 }
116 }
117}
118
119#[inline(always)]
120pub(crate) unsafe fn cast_range<T, U>(ptr: Range<NonNull<T>>) -> Range<NonNull<U>> {
121 ptr.start.cast()..ptr.end.cast()
122}
123
124#[must_use]
126#[inline(always)]
127pub(crate) const fn str_from_utf8(bytes: NonNull<[u8]>) -> NonNull<str> {
128 unsafe { NonNull::new_unchecked(bytes.as_ptr() as *mut str) }
129}
130
131#[must_use]
133#[inline(always)]
134pub(crate) const fn str_bytes(str: NonNull<str>) -> NonNull<[u8]> {
135 unsafe { NonNull::new_unchecked(str.as_ptr() as *mut [u8]) }
136}
137
138#[must_use]
140#[inline(always)]
141pub(crate) const fn str_len(str: NonNull<str>) -> usize {
142 str_bytes(str).len()
143}
144
145#[inline(always)]
150pub(crate) unsafe fn write_with<T>(ptr: NonNull<T>, f: impl FnOnce() -> T) {
151 unsafe { ptr.write(f()) };
152}