Skip to content

Commit ca1512b

Browse files
Forward missing implementations to the view
1 parent 101b3b6 commit ca1512b

File tree

1 file changed

+16
-222
lines changed

1 file changed

+16
-222
lines changed

src/vec.rs

+16-222
Original file line numberDiff line numberDiff line change
@@ -952,38 +952,19 @@ impl<T, const N: usize> Vec<T, N> {
952952
where
953953
T: Clone,
954954
{
955-
if self.len + other.len() > self.capacity() {
956-
// won't fit in the `Vec`; don't modify anything and return an error
957-
Err(())
958-
} else {
959-
for elem in other {
960-
unsafe {
961-
self.push_unchecked(elem.clone());
962-
}
963-
}
964-
Ok(())
965-
}
955+
self.as_mut_view().extend_from_slice(other)
966956
}
967957

968958
/// Removes the last element from a vector and returns it, or `None` if it's empty
969959
pub fn pop(&mut self) -> Option<T> {
970-
if self.len != 0 {
971-
Some(unsafe { self.pop_unchecked() })
972-
} else {
973-
None
974-
}
960+
self.as_mut_view().pop()
975961
}
976962

977963
/// Appends an `item` to the back of the collection
978964
///
979965
/// Returns back the `item` if the vector is full
980966
pub fn push(&mut self, item: T) -> Result<(), T> {
981-
if self.len < self.capacity() {
982-
unsafe { self.push_unchecked(item) }
983-
Ok(())
984-
} else {
985-
Err(item)
986-
}
967+
self.as_mut_view().push(item)
987968
}
988969

989970
/// Removes the last element from a vector and returns it
@@ -992,10 +973,7 @@ impl<T, const N: usize> Vec<T, N> {
992973
///
993974
/// This assumes the vec to have at least one element.
994975
pub unsafe fn pop_unchecked(&mut self) -> T {
995-
debug_assert!(!self.is_empty());
996-
997-
self.len -= 1;
998-
self.buffer.get_unchecked_mut(self.len).as_ptr().read()
976+
self.as_mut_view().pop_unchecked()
999977
}
1000978

1001979
/// Appends an `item` to the back of the collection
@@ -1004,36 +982,12 @@ impl<T, const N: usize> Vec<T, N> {
1004982
///
1005983
/// This assumes the vec is not full.
1006984
pub unsafe fn push_unchecked(&mut self, item: T) {
1007-
// NOTE(ptr::write) the memory slot that we are about to write to is uninitialized. We
1008-
// use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory
1009-
debug_assert!(!self.is_full());
1010-
1011-
*self.buffer.get_unchecked_mut(self.len) = MaybeUninit::new(item);
1012-
1013-
self.len += 1;
985+
self.as_mut_view().push_unchecked(item)
1014986
}
1015987

1016988
/// Shortens the vector, keeping the first `len` elements and dropping the rest.
1017989
pub fn truncate(&mut self, len: usize) {
1018-
// This is safe because:
1019-
//
1020-
// * the slice passed to `drop_in_place` is valid; the `len > self.len`
1021-
// case avoids creating an invalid slice, and
1022-
// * the `len` of the vector is shrunk before calling `drop_in_place`,
1023-
// such that no value will be dropped twice in case `drop_in_place`
1024-
// were to panic once (if it panics twice, the program aborts).
1025-
unsafe {
1026-
// Note: It's intentional that this is `>` and not `>=`.
1027-
// Changing it to `>=` has negative performance
1028-
// implications in some cases. See rust-lang/rust#78884 for more.
1029-
if len > self.len {
1030-
return;
1031-
}
1032-
let remaining_len = self.len - len;
1033-
let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len);
1034-
self.len = len;
1035-
ptr::drop_in_place(s);
1036-
}
990+
self.as_mut_view().truncate(len)
1037991
}
1038992

1039993
/// Resizes the Vec in-place so that len is equal to new_len.
@@ -1048,19 +1002,7 @@ impl<T, const N: usize> Vec<T, N> {
10481002
where
10491003
T: Clone,
10501004
{
1051-
if new_len > self.capacity() {
1052-
return Err(());
1053-
}
1054-
1055-
if new_len > self.len {
1056-
while self.len < new_len {
1057-
self.push(value.clone()).ok();
1058-
}
1059-
} else {
1060-
self.truncate(new_len);
1061-
}
1062-
1063-
Ok(())
1005+
self.as_mut_view().resize(new_len, value)
10641006
}
10651007

10661008
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
@@ -1075,7 +1017,7 @@ impl<T, const N: usize> Vec<T, N> {
10751017
where
10761018
T: Clone + Default,
10771019
{
1078-
self.resize(new_len, T::default())
1020+
self.as_mut_view().resize_default(new_len)
10791021
}
10801022

10811023
/// Forces the length of the vector to `new_len`.
@@ -1202,8 +1144,7 @@ impl<T, const N: usize> Vec<T, N> {
12021144
/// assert_eq!(&*v, ["baz", "qux"]);
12031145
/// ```
12041146
pub fn swap_remove(&mut self, index: usize) -> T {
1205-
assert!(index < self.len);
1206-
unsafe { self.swap_remove_unchecked(index) }
1147+
self.as_mut_view().swap_remove(index)
12071148
}
12081149

12091150
/// Removes an element from the vector and returns it.
@@ -1234,13 +1175,7 @@ impl<T, const N: usize> Vec<T, N> {
12341175
/// assert_eq!(&*v, ["baz", "qux"]);
12351176
/// ```
12361177
pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T {
1237-
let length = self.len();
1238-
debug_assert!(index < length);
1239-
let value = ptr::read(self.as_ptr().add(index));
1240-
let base_ptr = self.as_mut_ptr();
1241-
ptr::copy(base_ptr.add(length - 1), base_ptr.add(index), 1);
1242-
self.len -= 1;
1243-
value
1178+
self.as_mut_view().swap_remove_unchecked(index)
12441179
}
12451180

12461181
/// Returns true if the vec is full
@@ -1322,35 +1257,7 @@ impl<T, const N: usize> Vec<T, N> {
13221257
/// assert_eq!(vec, [1, 4, 2, 3, 5]);
13231258
/// ```
13241259
pub fn insert(&mut self, index: usize, element: T) -> Result<(), T> {
1325-
let len = self.len();
1326-
if index > len {
1327-
panic!(
1328-
"insertion index (is {}) should be <= len (is {})",
1329-
index, len
1330-
);
1331-
}
1332-
1333-
// check there's space for the new element
1334-
if self.is_full() {
1335-
return Err(element);
1336-
}
1337-
1338-
unsafe {
1339-
// infallible
1340-
// The spot to put the new value
1341-
{
1342-
let p = self.as_mut_ptr().add(index);
1343-
// Shift everything over to make space. (Duplicating the
1344-
// `index`th element into two consecutive places.)
1345-
ptr::copy(p, p.offset(1), len - index);
1346-
// Write it in, overwriting the first copy of the `index`th
1347-
// element.
1348-
ptr::write(p, element);
1349-
}
1350-
self.set_len(len + 1);
1351-
}
1352-
1353-
Ok(())
1260+
self.as_mut_view().insert(index, element)
13541261
}
13551262

13561263
/// Removes and returns the element at position `index` within the vector,
@@ -1379,26 +1286,7 @@ impl<T, const N: usize> Vec<T, N> {
13791286
/// assert_eq!(v, [1, 3]);
13801287
/// ```
13811288
pub fn remove(&mut self, index: usize) -> T {
1382-
let len = self.len();
1383-
if index >= len {
1384-
panic!("removal index (is {}) should be < len (is {})", index, len);
1385-
}
1386-
unsafe {
1387-
// infallible
1388-
let ret;
1389-
{
1390-
// the place we are taking from.
1391-
let ptr = self.as_mut_ptr().add(index);
1392-
// copy it out, unsafely having a copy of the value on
1393-
// the stack and in the vector at the same time.
1394-
ret = ptr::read(ptr);
1395-
1396-
// Shift everything down to fill in that spot.
1397-
ptr::copy(ptr.offset(1), ptr, len - index - 1);
1398-
}
1399-
self.set_len(len - 1);
1400-
ret
1401-
}
1289+
self.as_mut_view().remove(index)
14021290
}
14031291

14041292
/// Retains only the elements specified by the predicate.
@@ -1429,11 +1317,11 @@ impl<T, const N: usize> Vec<T, N> {
14291317
/// vec.retain(|_| *iter.next().unwrap());
14301318
/// assert_eq!(vec, [2, 3, 5]);
14311319
/// ```
1432-
pub fn retain<F>(&mut self, mut f: F)
1320+
pub fn retain<F>(&mut self, f: F)
14331321
where
14341322
F: FnMut(&T) -> bool,
14351323
{
1436-
self.retain_mut(|elem| f(elem));
1324+
self.as_mut_view().retain(f)
14371325
}
14381326

14391327
/// Retains only the elements specified by the predicate, passing a mutable reference to it.
@@ -1458,105 +1346,11 @@ impl<T, const N: usize> Vec<T, N> {
14581346
/// });
14591347
/// assert_eq!(vec, [2, 3, 4]);
14601348
/// ```
1461-
pub fn retain_mut<F>(&mut self, mut f: F)
1349+
pub fn retain_mut<F>(&mut self, f: F)
14621350
where
14631351
F: FnMut(&mut T) -> bool,
14641352
{
1465-
let original_len = self.len();
1466-
// Avoid double drop if the drop guard is not executed,
1467-
// since we may make some holes during the process.
1468-
unsafe { self.set_len(0) };
1469-
1470-
// Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked]
1471-
// |<- processed len ->| ^- next to check
1472-
// |<- deleted cnt ->|
1473-
// |<- original_len ->|
1474-
// Kept: Elements which predicate returns true on.
1475-
// Hole: Moved or dropped element slot.
1476-
// Unchecked: Unchecked valid elements.
1477-
//
1478-
// This drop guard will be invoked when predicate or `drop` of element panicked.
1479-
// It shifts unchecked elements to cover holes and `set_len` to the correct length.
1480-
// In cases when predicate and `drop` never panick, it will be optimized out.
1481-
struct BackshiftOnDrop<'a, T, const N: usize> {
1482-
v: &'a mut Vec<T, N>,
1483-
processed_len: usize,
1484-
deleted_cnt: usize,
1485-
original_len: usize,
1486-
}
1487-
1488-
impl<T, const N: usize> Drop for BackshiftOnDrop<'_, T, N> {
1489-
fn drop(&mut self) {
1490-
if self.deleted_cnt > 0 {
1491-
// SAFETY: Trailing unchecked items must be valid since we never touch them.
1492-
unsafe {
1493-
ptr::copy(
1494-
self.v.as_ptr().add(self.processed_len),
1495-
self.v
1496-
.as_mut_ptr()
1497-
.add(self.processed_len - self.deleted_cnt),
1498-
self.original_len - self.processed_len,
1499-
);
1500-
}
1501-
}
1502-
// SAFETY: After filling holes, all items are in contiguous memory.
1503-
unsafe {
1504-
self.v.set_len(self.original_len - self.deleted_cnt);
1505-
}
1506-
}
1507-
}
1508-
1509-
let mut g = BackshiftOnDrop {
1510-
v: self,
1511-
processed_len: 0,
1512-
deleted_cnt: 0,
1513-
original_len,
1514-
};
1515-
1516-
fn process_loop<F, T, const N: usize, const DELETED: bool>(
1517-
original_len: usize,
1518-
f: &mut F,
1519-
g: &mut BackshiftOnDrop<'_, T, N>,
1520-
) where
1521-
F: FnMut(&mut T) -> bool,
1522-
{
1523-
while g.processed_len != original_len {
1524-
let p = g.v.as_mut_ptr();
1525-
// SAFETY: Unchecked element must be valid.
1526-
let cur = unsafe { &mut *p.add(g.processed_len) };
1527-
if !f(cur) {
1528-
// Advance early to avoid double drop if `drop_in_place` panicked.
1529-
g.processed_len += 1;
1530-
g.deleted_cnt += 1;
1531-
// SAFETY: We never touch this element again after dropped.
1532-
unsafe { ptr::drop_in_place(cur) };
1533-
// We already advanced the counter.
1534-
if DELETED {
1535-
continue;
1536-
} else {
1537-
break;
1538-
}
1539-
}
1540-
if DELETED {
1541-
// SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
1542-
// We use copy for move, and never touch this element again.
1543-
unsafe {
1544-
let hole_slot = p.add(g.processed_len - g.deleted_cnt);
1545-
ptr::copy_nonoverlapping(cur, hole_slot, 1);
1546-
}
1547-
}
1548-
g.processed_len += 1;
1549-
}
1550-
}
1551-
1552-
// Stage 1: Nothing was deleted.
1553-
process_loop::<F, T, N, false>(original_len, &mut f, &mut g);
1554-
1555-
// Stage 2: Some elements were deleted.
1556-
process_loop::<F, T, N, true>(original_len, &mut f, &mut g);
1557-
1558-
// All item are processed. This can be optimized to `set_len` by LLVM.
1559-
drop(g);
1353+
self.as_mut_view().retain_mut(f)
15601354
}
15611355
}
15621356

0 commit comments

Comments
 (0)