Skip to content

Commit 47b1dbd

Browse files
committed
Implement to_vec() in terms of to_boxed_slice()
1 parent f90aeeb commit 47b1dbd

File tree

1 file changed

+6
-57
lines changed

1 file changed

+6
-57
lines changed

library/alloc/src/slice.rs

+6-57
Original file line numberDiff line numberDiff line change
@@ -160,60 +160,22 @@ mod hack {
160160
}
161161

162162
#[inline]
163-
pub fn to_vec<T: ConvertVec, A: Allocator>(s: &[T], alloc: A) -> Vec<T, A> {
164-
T::to_vec(s, alloc)
163+
pub fn to_vec<T: ConvertBoxed, A: Allocator>(s: &[T], alloc: A) -> Vec<T, A> {
164+
into_vec(to_boxed_slice(s, alloc))
165165
}
166166

167167
#[inline]
168-
pub fn to_boxed_slice<T: ConvertVec, A: Allocator>(s: &[T], alloc: A) -> Box<[T], A> {
168+
pub fn to_boxed_slice<T: ConvertBoxed, A: Allocator>(s: &[T], alloc: A) -> Box<[T], A> {
169169
T::to_boxed_slice(s, alloc)
170170
}
171171

172-
pub trait ConvertVec {
173-
fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A>
174-
where
175-
Self: Sized;
176-
172+
pub trait ConvertBoxed {
177173
fn to_boxed_slice<A: Allocator>(s: &[Self], alloc: A) -> Box<[Self], A>
178174
where
179175
Self: Sized;
180176
}
181177

182-
impl<T: Clone> ConvertVec for T {
183-
#[inline]
184-
default fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
185-
struct DropGuard<'a, T, A: Allocator> {
186-
vec: &'a mut Vec<T, A>,
187-
num_init: usize,
188-
}
189-
impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> {
190-
#[inline]
191-
fn drop(&mut self) {
192-
// SAFETY:
193-
// items were marked initialized in the loop below
194-
unsafe {
195-
self.vec.set_len(self.num_init);
196-
}
197-
}
198-
}
199-
let mut vec = Vec::with_capacity_in(s.len(), alloc);
200-
let mut guard = DropGuard { vec: &mut vec, num_init: 0 };
201-
let slots = guard.vec.spare_capacity_mut();
202-
// .take(slots.len()) is necessary for LLVM to remove bounds checks
203-
// and has better codegen than zip.
204-
for (i, b) in s.iter().enumerate().take(slots.len()) {
205-
guard.num_init = i;
206-
slots[i].write(b.clone());
207-
}
208-
core::mem::forget(guard);
209-
// SAFETY:
210-
// the vec was allocated and initialized above to at least this length.
211-
unsafe {
212-
vec.set_len(s.len());
213-
}
214-
vec
215-
}
216-
178+
impl<T: Clone> ConvertBoxed for T {
217179
#[inline]
218180
default fn to_boxed_slice<A: Allocator>(s: &[Self], alloc: A) -> Box<[Self], A> {
219181
struct DropGuard<T> {
@@ -244,20 +206,7 @@ mod hack {
244206
}
245207
}
246208

247-
impl<T: Copy> ConvertVec for T {
248-
#[inline]
249-
fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
250-
let mut v = Vec::with_capacity_in(s.len(), alloc);
251-
// SAFETY:
252-
// allocated above with the capacity of `s`, and initialize to `s.len()` in
253-
// ptr::copy_to_non_overlapping below.
254-
unsafe {
255-
s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len());
256-
v.set_len(s.len());
257-
}
258-
v
259-
}
260-
209+
impl<T: Copy> ConvertBoxed for T {
261210
#[inline]
262211
fn to_boxed_slice<A: Allocator>(s: &[Self], alloc: A) -> Box<[Self], A> {
263212
let mut boxed = Box::new_uninit_slice_in(s.len(), alloc);

0 commit comments

Comments
 (0)