Skip to content

Commit 0af5f17

Browse files
Forward missing implementations to the view
1 parent 805037b commit 0af5f17

File tree

1 file changed

+16
-222
lines changed

1 file changed

+16
-222
lines changed

src/vec.rs

Lines changed: 16 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -998,38 +998,19 @@ impl<T, const N: usize> Vec<T, N> {
998998
where
999999
T: Clone,
10001000
{
1001-
if self.len + other.len() > self.capacity() {
1002-
// won't fit in the `Vec`; don't modify anything and return an error
1003-
Err(())
1004-
} else {
1005-
for elem in other {
1006-
unsafe {
1007-
self.push_unchecked(elem.clone());
1008-
}
1009-
}
1010-
Ok(())
1011-
}
1001+
self.as_mut_view().extend_from_slice(other)
10121002
}
10131003

10141004
/// Removes the last element from a vector and returns it, or `None` if it's empty
10151005
pub fn pop(&mut self) -> Option<T> {
1016-
if self.len != 0 {
1017-
Some(unsafe { self.pop_unchecked() })
1018-
} else {
1019-
None
1020-
}
1006+
self.as_mut_view().pop()
10211007
}
10221008

10231009
/// Appends an `item` to the back of the collection
10241010
///
10251011
/// Returns back the `item` if the vector is full
10261012
pub fn push(&mut self, item: T) -> Result<(), T> {
1027-
if self.len < self.capacity() {
1028-
unsafe { self.push_unchecked(item) }
1029-
Ok(())
1030-
} else {
1031-
Err(item)
1032-
}
1013+
self.as_mut_view().push(item)
10331014
}
10341015

10351016
/// Removes the last element from a vector and returns it
@@ -1038,10 +1019,7 @@ impl<T, const N: usize> Vec<T, N> {
10381019
///
10391020
/// This assumes the vec to have at least one element.
10401021
pub unsafe fn pop_unchecked(&mut self) -> T {
1041-
debug_assert!(!self.is_empty());
1042-
1043-
self.len -= 1;
1044-
self.buffer.get_unchecked_mut(self.len).as_ptr().read()
1022+
self.as_mut_view().pop_unchecked()
10451023
}
10461024

10471025
/// Appends an `item` to the back of the collection
@@ -1050,36 +1028,12 @@ impl<T, const N: usize> Vec<T, N> {
10501028
///
10511029
/// This assumes the vec is not full.
10521030
pub unsafe fn push_unchecked(&mut self, item: T) {
1053-
// NOTE(ptr::write) the memory slot that we are about to write to is uninitialized. We
1054-
// use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory
1055-
debug_assert!(!self.is_full());
1056-
1057-
*self.buffer.get_unchecked_mut(self.len) = MaybeUninit::new(item);
1058-
1059-
self.len += 1;
1031+
self.as_mut_view().push_unchecked(item)
10601032
}
10611033

10621034
/// Shortens the vector, keeping the first `len` elements and dropping the rest.
10631035
pub fn truncate(&mut self, len: usize) {
1064-
// This is safe because:
1065-
//
1066-
// * the slice passed to `drop_in_place` is valid; the `len > self.len`
1067-
// case avoids creating an invalid slice, and
1068-
// * the `len` of the vector is shrunk before calling `drop_in_place`,
1069-
// such that no value will be dropped twice in case `drop_in_place`
1070-
// were to panic once (if it panics twice, the program aborts).
1071-
unsafe {
1072-
// Note: It's intentional that this is `>` and not `>=`.
1073-
// Changing it to `>=` has negative performance
1074-
// implications in some cases. See rust-lang/rust#78884 for more.
1075-
if len > self.len {
1076-
return;
1077-
}
1078-
let remaining_len = self.len - len;
1079-
let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len);
1080-
self.len = len;
1081-
ptr::drop_in_place(s);
1082-
}
1036+
self.as_mut_view().truncate(len)
10831037
}
10841038

10851039
/// Resizes the Vec in-place so that len is equal to new_len.
@@ -1094,19 +1048,7 @@ impl<T, const N: usize> Vec<T, N> {
10941048
where
10951049
T: Clone,
10961050
{
1097-
if new_len > self.capacity() {
1098-
return Err(());
1099-
}
1100-
1101-
if new_len > self.len {
1102-
while self.len < new_len {
1103-
self.push(value.clone()).ok();
1104-
}
1105-
} else {
1106-
self.truncate(new_len);
1107-
}
1108-
1109-
Ok(())
1051+
self.as_mut_view().resize(new_len, value)
11101052
}
11111053

11121054
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
@@ -1121,7 +1063,7 @@ impl<T, const N: usize> Vec<T, N> {
11211063
where
11221064
T: Clone + Default,
11231065
{
1124-
self.resize(new_len, T::default())
1066+
self.as_mut_view().resize_default(new_len)
11251067
}
11261068

11271069
/// Forces the length of the vector to `new_len`.
@@ -1248,8 +1190,7 @@ impl<T, const N: usize> Vec<T, N> {
12481190
/// assert_eq!(&*v, ["baz", "qux"]);
12491191
/// ```
12501192
pub fn swap_remove(&mut self, index: usize) -> T {
1251-
assert!(index < self.len);
1252-
unsafe { self.swap_remove_unchecked(index) }
1193+
self.as_mut_view().swap_remove(index)
12531194
}
12541195

12551196
/// Removes an element from the vector and returns it.
@@ -1280,13 +1221,7 @@ impl<T, const N: usize> Vec<T, N> {
12801221
/// assert_eq!(&*v, ["baz", "qux"]);
12811222
/// ```
12821223
pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T {
1283-
let length = self.len();
1284-
debug_assert!(index < length);
1285-
let value = ptr::read(self.as_ptr().add(index));
1286-
let base_ptr = self.as_mut_ptr();
1287-
ptr::copy(base_ptr.add(length - 1), base_ptr.add(index), 1);
1288-
self.len -= 1;
1289-
value
1224+
self.as_mut_view().swap_remove_unchecked(index)
12901225
}
12911226

12921227
/// Returns true if the vec is full
@@ -1368,35 +1303,7 @@ impl<T, const N: usize> Vec<T, N> {
13681303
/// assert_eq!(vec, [1, 4, 2, 3, 5]);
13691304
/// ```
13701305
pub fn insert(&mut self, index: usize, element: T) -> Result<(), T> {
1371-
let len = self.len();
1372-
if index > len {
1373-
panic!(
1374-
"insertion index (is {}) should be <= len (is {})",
1375-
index, len
1376-
);
1377-
}
1378-
1379-
// check there's space for the new element
1380-
if self.is_full() {
1381-
return Err(element);
1382-
}
1383-
1384-
unsafe {
1385-
// infallible
1386-
// The spot to put the new value
1387-
{
1388-
let p = self.as_mut_ptr().add(index);
1389-
// Shift everything over to make space. (Duplicating the
1390-
// `index`th element into two consecutive places.)
1391-
ptr::copy(p, p.offset(1), len - index);
1392-
// Write it in, overwriting the first copy of the `index`th
1393-
// element.
1394-
ptr::write(p, element);
1395-
}
1396-
self.set_len(len + 1);
1397-
}
1398-
1399-
Ok(())
1306+
self.as_mut_view().insert(index, element)
14001307
}
14011308

14021309
/// Removes and returns the element at position `index` within the vector,
@@ -1425,26 +1332,7 @@ impl<T, const N: usize> Vec<T, N> {
14251332
/// assert_eq!(v, [1, 3]);
14261333
/// ```
14271334
pub fn remove(&mut self, index: usize) -> T {
1428-
let len = self.len();
1429-
if index >= len {
1430-
panic!("removal index (is {}) should be < len (is {})", index, len);
1431-
}
1432-
unsafe {
1433-
// infallible
1434-
let ret;
1435-
{
1436-
// the place we are taking from.
1437-
let ptr = self.as_mut_ptr().add(index);
1438-
// copy it out, unsafely having a copy of the value on
1439-
// the stack and in the vector at the same time.
1440-
ret = ptr::read(ptr);
1441-
1442-
// Shift everything down to fill in that spot.
1443-
ptr::copy(ptr.offset(1), ptr, len - index - 1);
1444-
}
1445-
self.set_len(len - 1);
1446-
ret
1447-
}
1335+
self.as_mut_view().remove(index)
14481336
}
14491337

14501338
/// Retains only the elements specified by the predicate.
@@ -1475,11 +1363,11 @@ impl<T, const N: usize> Vec<T, N> {
14751363
/// vec.retain(|_| *iter.next().unwrap());
14761364
/// assert_eq!(vec, [2, 3, 5]);
14771365
/// ```
1478-
pub fn retain<F>(&mut self, mut f: F)
1366+
pub fn retain<F>(&mut self, f: F)
14791367
where
14801368
F: FnMut(&T) -> bool,
14811369
{
1482-
self.retain_mut(|elem| f(elem));
1370+
self.as_mut_view().retain(f)
14831371
}
14841372

14851373
/// Retains only the elements specified by the predicate, passing a mutable reference to it.
@@ -1504,105 +1392,11 @@ impl<T, const N: usize> Vec<T, N> {
15041392
/// });
15051393
/// assert_eq!(vec, [2, 3, 4]);
15061394
/// ```
1507-
pub fn retain_mut<F>(&mut self, mut f: F)
1395+
pub fn retain_mut<F>(&mut self, f: F)
15081396
where
15091397
F: FnMut(&mut T) -> bool,
15101398
{
1511-
let original_len = self.len();
1512-
// Avoid double drop if the drop guard is not executed,
1513-
// since we may make some holes during the process.
1514-
unsafe { self.set_len(0) };
1515-
1516-
// Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked]
1517-
// |<- processed len ->| ^- next to check
1518-
// |<- deleted cnt ->|
1519-
// |<- original_len ->|
1520-
// Kept: Elements which predicate returns true on.
1521-
// Hole: Moved or dropped element slot.
1522-
// Unchecked: Unchecked valid elements.
1523-
//
1524-
// This drop guard will be invoked when predicate or `drop` of element panicked.
1525-
// It shifts unchecked elements to cover holes and `set_len` to the correct length.
1526-
// In cases when predicate and `drop` never panick, it will be optimized out.
1527-
struct BackshiftOnDrop<'a, T, const N: usize> {
1528-
v: &'a mut Vec<T, N>,
1529-
processed_len: usize,
1530-
deleted_cnt: usize,
1531-
original_len: usize,
1532-
}
1533-
1534-
impl<T, const N: usize> Drop for BackshiftOnDrop<'_, T, N> {
1535-
fn drop(&mut self) {
1536-
if self.deleted_cnt > 0 {
1537-
// SAFETY: Trailing unchecked items must be valid since we never touch them.
1538-
unsafe {
1539-
ptr::copy(
1540-
self.v.as_ptr().add(self.processed_len),
1541-
self.v
1542-
.as_mut_ptr()
1543-
.add(self.processed_len - self.deleted_cnt),
1544-
self.original_len - self.processed_len,
1545-
);
1546-
}
1547-
}
1548-
// SAFETY: After filling holes, all items are in contiguous memory.
1549-
unsafe {
1550-
self.v.set_len(self.original_len - self.deleted_cnt);
1551-
}
1552-
}
1553-
}
1554-
1555-
let mut g = BackshiftOnDrop {
1556-
v: self,
1557-
processed_len: 0,
1558-
deleted_cnt: 0,
1559-
original_len,
1560-
};
1561-
1562-
fn process_loop<F, T, const N: usize, const DELETED: bool>(
1563-
original_len: usize,
1564-
f: &mut F,
1565-
g: &mut BackshiftOnDrop<'_, T, N>,
1566-
) where
1567-
F: FnMut(&mut T) -> bool,
1568-
{
1569-
while g.processed_len != original_len {
1570-
let p = g.v.as_mut_ptr();
1571-
// SAFETY: Unchecked element must be valid.
1572-
let cur = unsafe { &mut *p.add(g.processed_len) };
1573-
if !f(cur) {
1574-
// Advance early to avoid double drop if `drop_in_place` panicked.
1575-
g.processed_len += 1;
1576-
g.deleted_cnt += 1;
1577-
// SAFETY: We never touch this element again after dropped.
1578-
unsafe { ptr::drop_in_place(cur) };
1579-
// We already advanced the counter.
1580-
if DELETED {
1581-
continue;
1582-
} else {
1583-
break;
1584-
}
1585-
}
1586-
if DELETED {
1587-
// SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
1588-
// We use copy for move, and never touch this element again.
1589-
unsafe {
1590-
let hole_slot = p.add(g.processed_len - g.deleted_cnt);
1591-
ptr::copy_nonoverlapping(cur, hole_slot, 1);
1592-
}
1593-
}
1594-
g.processed_len += 1;
1595-
}
1596-
}
1597-
1598-
// Stage 1: Nothing was deleted.
1599-
process_loop::<F, T, N, false>(original_len, &mut f, &mut g);
1600-
1601-
// Stage 2: Some elements were deleted.
1602-
process_loop::<F, T, N, true>(original_len, &mut f, &mut g);
1603-
1604-
// All item are processed. This can be optimized to `set_len` by LLVM.
1605-
drop(g);
1399+
self.as_mut_view().retain_mut(f)
16061400
}
16071401

16081402
/// Returns the remaining spare capacity of the vector as a slice of `MaybeUninit<T>`.

0 commit comments

Comments
 (0)