mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Use NonNull in merge_sort
This is more clear about the intent of the pointer and avoids problems if the allocation returns a null pointer.
This commit is contained in:
parent
e098eb17e1
commit
703ff60d9f
@ -1203,7 +1203,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
// `is_less` panics. When merging two sorted runs, this buffer holds a copy of the shorter run,
|
||||
// which will always have length at most `len / 2`.
|
||||
let buf = BufGuard::new(len / 2, elem_alloc_fn, elem_dealloc_fn);
|
||||
let buf_ptr = buf.buf_ptr;
|
||||
let buf_ptr = buf.buf_ptr.as_ptr();
|
||||
|
||||
let mut runs = RunVec::new(run_alloc_fn, run_dealloc_fn);
|
||||
|
||||
@ -1298,7 +1298,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
where
|
||||
ElemDeallocF: Fn(*mut T, usize),
|
||||
{
|
||||
buf_ptr: *mut T,
|
||||
buf_ptr: ptr::NonNull<T>,
|
||||
capacity: usize,
|
||||
elem_dealloc_fn: ElemDeallocF,
|
||||
}
|
||||
@ -1315,7 +1315,11 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
where
|
||||
ElemAllocF: Fn(usize) -> *mut T,
|
||||
{
|
||||
Self { buf_ptr: elem_alloc_fn(len), capacity: len, elem_dealloc_fn }
|
||||
Self {
|
||||
buf_ptr: ptr::NonNull::new(elem_alloc_fn(len)).unwrap(),
|
||||
capacity: len,
|
||||
elem_dealloc_fn,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1324,7 +1328,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
ElemDeallocF: Fn(*mut T, usize),
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
(self.elem_dealloc_fn)(self.buf_ptr, self.capacity);
|
||||
(self.elem_dealloc_fn)(self.buf_ptr.as_ptr(), self.capacity);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1333,7 +1337,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
RunAllocF: Fn(usize) -> *mut TimSortRun,
|
||||
RunDeallocF: Fn(*mut TimSortRun, usize),
|
||||
{
|
||||
buf_ptr: *mut TimSortRun,
|
||||
buf_ptr: ptr::NonNull<TimSortRun>,
|
||||
capacity: usize,
|
||||
len: usize,
|
||||
run_alloc_fn: RunAllocF,
|
||||
@ -1350,7 +1354,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
const START_RUN_CAPACITY: usize = 16;
|
||||
|
||||
Self {
|
||||
buf_ptr: run_alloc_fn(START_RUN_CAPACITY),
|
||||
buf_ptr: ptr::NonNull::new(run_alloc_fn(START_RUN_CAPACITY)).unwrap(),
|
||||
capacity: START_RUN_CAPACITY,
|
||||
len: 0,
|
||||
run_alloc_fn,
|
||||
@ -1361,15 +1365,15 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
fn push(&mut self, val: TimSortRun) {
|
||||
if self.len == self.capacity {
|
||||
let old_capacity = self.capacity;
|
||||
let old_buf_ptr = self.buf_ptr;
|
||||
let old_buf_ptr = self.buf_ptr.as_ptr();
|
||||
|
||||
self.capacity = self.capacity * 2;
|
||||
self.buf_ptr = (self.run_alloc_fn)(self.capacity);
|
||||
self.buf_ptr = ptr::NonNull::new((self.run_alloc_fn)(self.capacity)).unwrap();
|
||||
|
||||
// SAFETY: buf_ptr new and old were correctly allocated and old_buf_ptr has
|
||||
// old_capacity valid elements.
|
||||
unsafe {
|
||||
ptr::copy_nonoverlapping(old_buf_ptr, self.buf_ptr, old_capacity);
|
||||
ptr::copy_nonoverlapping(old_buf_ptr, self.buf_ptr.as_ptr(), old_capacity);
|
||||
}
|
||||
|
||||
(self.run_dealloc_fn)(old_buf_ptr, old_capacity);
|
||||
@ -1377,7 +1381,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
|
||||
// SAFETY: The invariant was just checked.
|
||||
unsafe {
|
||||
self.buf_ptr.add(self.len).write(val);
|
||||
self.buf_ptr.as_ptr().add(self.len).write(val);
|
||||
}
|
||||
self.len += 1;
|
||||
}
|
||||
@ -1390,7 +1394,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
// SAFETY: buf_ptr needs to be valid and len invariant upheld.
|
||||
unsafe {
|
||||
// the place we are taking from.
|
||||
let ptr = self.buf_ptr.add(index);
|
||||
let ptr = self.buf_ptr.as_ptr().add(index);
|
||||
|
||||
// Shift everything down to fill in that spot.
|
||||
ptr::copy(ptr.add(1), ptr, self.len - index - 1);
|
||||
@ -1400,7 +1404,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
|
||||
fn as_slice(&self) -> &[TimSortRun] {
|
||||
// SAFETY: Safe as long as buf_ptr is valid and len invariant was upheld.
|
||||
unsafe { &*ptr::slice_from_raw_parts(self.buf_ptr, self.len) }
|
||||
unsafe { &*ptr::slice_from_raw_parts(self.buf_ptr.as_ptr(), self.len) }
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
@ -1419,7 +1423,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
if index < self.len {
|
||||
// SAFETY: buf_ptr and len invariant must be upheld.
|
||||
unsafe {
|
||||
return &*(self.buf_ptr.add(index));
|
||||
return &*(self.buf_ptr.as_ptr().add(index));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1436,7 +1440,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
if index < self.len {
|
||||
// SAFETY: buf_ptr and len invariant must be upheld.
|
||||
unsafe {
|
||||
return &mut *(self.buf_ptr.add(index));
|
||||
return &mut *(self.buf_ptr.as_ptr().add(index));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1452,7 +1456,7 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
|
||||
fn drop(&mut self) {
|
||||
// As long as TimSortRun is Copy we don't need to drop them individually but just the
|
||||
// whole allocation.
|
||||
(self.run_dealloc_fn)(self.buf_ptr, self.capacity);
|
||||
(self.run_dealloc_fn)(self.buf_ptr.as_ptr(), self.capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user